这个应该属于撸一个适合自己的小游戏框架的第三篇。上一篇是Unity中的颜色转换,让Log信息更炫酷。
然后今天整理了一个之前copy的网格合并的代码。
网格合并
就是把多个分散物体(单个物体有单个mesh)组成的物体,合并一下,用一个mesh就能显示出来。来达到优化性能的效果 ,这个很多人写过。直接贴代码了。
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class CombineMesh : MonoBehaviour {
//mesh目录
static string meshDir = "Assets/";
[MenuItem("GameObject/合并网格", priority = 0)]
static void Combine()
{
GameObject[] objs = Selection.gameObjects;
for (int j = 0; j < objs.Length; j++)
{
MeshFilter[] meshfilters = objs[j].GetComponentsInChildren<MeshFilter>();
CombineInstance[] combine = new CombineInstance[meshfilters.Length];
Matrix4x4 matrix = objs[j].transform.worldToLocalMatrix;
for (int i = 0; i < meshfilters.Length; i++)
{
MeshFilter mf = meshfilters[i];
MeshRenderer mr = mf.GetComponent<MeshRenderer>();
if (mr == null) continue;
combine[i].mesh = mf.sharedMesh;
combine[i].transform = matrix * mf.transform.localToWorldMatrix;
}
Mesh mesh = new Mesh();
mesh.name = objs[j].name;
mesh.CombineMeshes(combine, true);
string path = meshDir + mesh.name + ".asset";
AssetDatabase.CreateAsset(mesh, path);
}
AssetDatabase.Refresh();
}
}
Matrix4x4
关于这个东西,因为脚本用到了,但自己并不知道是什么鬼东西。就简单了解一下,不做深究。
以下是个人理解:就是用一个4X4的矩阵来表示一些3D变化。(例如平移,旋转,缩放等),大概就是一种更吊(更难理解)的控制物体Tranfrom状态的类型。
在这个脚本里用于记录子物体相对于父物体的世界坐标,达到合并网格不变形的效果。
关于InverseTransformPoint
为什么提到这个东西呢,因为在Unity圣典的对Matrix4x4描述里出现了这样的描述。
Transform.localToWorldMatrix 矩阵坐标自身到世界
描述
矩阵变换的点从自身坐标转为世界坐标(只读)。
如果你不熟悉使用矩阵为坐标转换,使用Transform.TransformPoint代替。
就是说我们脚本里面用的转换方法是可以用Transform.TransformPoint来代替了。于是我又做了InverseTransformPoint的测试。以下是我得出的结论。
//世界坐标转局部坐标,任意位置都可以。
public Vector3 WorldToLocalPos(Transform parent,Transform worldPos)
{
Vector3 LocalPos;
LocalPos = parent.InverseTransformPoint(worldPos.position);
return LocalPos;
}
//世界坐标(targetTrans)转相对(parent)的世界坐标。
//例:targetTrans的世界坐标是(1,1, 1)parent的世界坐标是(2,2,2)那么获得的相对坐标是以parent为坐标原点的(1,1,1)位置,即向量相加返回为(3,3,3)
//可以这么理解,相对于target的局部坐标转化成世界坐标。就是target的子物体的localPosition转成世界坐标。(只能转子物体,孙物体不行。)
//可以通过孙物体的世界坐标InverseTransformPoint转成相对于parent的子物体坐标。然后再TransformPoint转成世界坐标。(证明两个方法是互逆的)
//嗯,我都能获取到孙物体的世界坐标了还转什么呢?没太清楚这个方法的具体应用场景。
public Vector3 targetTransToWorldPos(Transform parent, Transform targetTrans)
{
Vector3 WorldPos;
WorldPos = parent.TransformPoint(targetTrans.localPosition);
return WorldPos;
}
最后,既然都一样,为什么不用Transform.TransformPoint代替呢,因为我们在脚本中网格合并需要的transform是Matrix4x4类型的。InverseTransformPoint返回的是Vector3 类型的。
以上。