Unity网格合并,Matrix4x4,和InverseTransformPoint的简单理解

这个应该属于撸一个适合自己的小游戏框架的第三篇。上一篇是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 类型的。

以上。

你可能感兴趣的:(unity3d,游戏开发,unity)