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 類型的。

以上。

發佈了27 篇原創文章 · 獲贊 29 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章