這個應該屬於擼一個適合自己的小遊戲框架的第三篇。上一篇是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 類型的。
以上。