首先明確一點,Mesh是一個類,MeshRenderer和MeshFilter都可以作為組件,掛載到GameObject上面,但是Mesh不可以。
Mesh: 譯作 網格,是一個數據結構,記載了組成一個GameObject的所有三角形面。
MeshFilter: 譯作 網格過濾器,記載着物體對應的所有Mesh的引用,當渲染GameObject時,通過MeshFilter獲取其對應的Mesh。
MeshFilter是一個從Unity老版本留存下來的叫法,實際上它並不過濾任何東西,如果換一個更准確的名字:MeshRefference 可能更好理解。
如果還沒完全理解,可以看下面這個例子:
先在Unity的Hierarchy界面建立一個空的GameObject,然后在其對應的Inspector界面上添加兩個組件,MeshFilter和MeshRenderer,可以看到MeshFilter下面的Mesh槽是空的,點擊右邊的小圓圈可以選擇系統自帶的Mesh,如下圖所示:
然后我們再在該物體上,點擊AddComponent,創建並添加MeshGenerator
腳本,腳本內容如下:
[RequireComponent(typeof(MeshFilter))]//這個腳本掛載的GameObject必須需要MeshFilter組件
public class MeshGenerator : MonoBehaviour
{
public Mesh mesh;
public Vector3[] vertices;//mesh的最基本數據,記錄每一個點
public int[] triangles;//mesh的最基本數據,記錄每一個組成三角形的三個點的index
void Start()
{
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;//把mesh傳給MeshFilter
CreateMeshData();//生成mesh的data信息
mesh.Clear();//清空自帶的mesh信息
mesh.vertices = vertices;
mesh.triangles = triangles;
}
//自己創建一個mesh
void CreateMeshData()
{
vertices = new Vector3[]
{
new Vector3(0, 0, 0),
new Vector3(0, 0, 1),
new Vector3(1, 0, 0),
};
triangles = new int[]
{
0, 1, 2//Unity里的索引順序是順時針,從上往下看是0,1,2
};
}
}
最后運行游戲,就可以在Scene界面下看到一個紫色的三角形了,由於沒有設定MeshRenderer中的Material,所以默認是紫色的,如下圖所示:
關於SharedMesh
從Unity的官方文檔中,我看到了MeshFilter不只含有Mesh,還有一個SharedMesh
SharedMesh可以理解為,Mesh類型的Prefab
如果在Asset文件里有一個Mesh文件(比如說3ds格式的),如果場景里有很多個物體,每一個物體都用到了該Mesh,對於每一個用到該mesh的物體,其上面都實例化了一個Mesh對象,如果對物體A的mesh進行改變,其他的Mesh不會改變。
但如果想同時對所有用到該對象的mesh進行改變,可以對SharedMesh進行操作,從而實現類似prefab的統一編輯操作。