1. 程式人生 > >Unity網格合併_材質合併

Unity網格合併_材質合併

從優化角度,Mesh需要合併。

從換裝的角度(這裡指的是換形狀、換組成部件的換裝,而不是掛點型的換裝),都需要網格合併、材質合併。如果是人物的換裝,那麼需要合併SkinnedMeshRenderer,並重刷對應的骨骼列表。

示例:

1,新建兩個Cube,和一個Cylinder。分別作為坦克的底盤(Cube_chassis)、炮塔(Cube_turret)、炮管(Cylinder_gun)。如下圖所示。

2,為了測試換裝,我們加入三個材質球,調整一下顏色,然後分別賦給底盤(Cube_chassis)、炮塔(Cube_turret)、炮管(Cylinder_gun)。

3,把炮塔(Cube_turret)和炮管(Cylinder_gun),變成底盤(Cube_chassis)的子物體。也就是說,新的模型,是以底盤為基礎的。

4,用CombineMeshes方法,合併mesh。並且用程式碼把【材質】也一起“合併”了。把下面的Combine_Test.cs檔案,拖拽到底盤(Cube_chassis)上,之後執行。

using UnityEngine; using System.Collections;   public class Combine_Test : MonoBehaviour {       // Use this for initialization     void Start ()     {         //---------------- 先獲取材質 -------------------------         //獲取自身和所有子物體中所有MeshRenderer元件         MeshRenderer[] meshRenderers = GetComponentsInChildren<MeshRenderer>();           //新建材質球陣列         Material[] mats = new Material[meshRenderers.Length];           for (int i = 0; i < meshRenderers.Length; i++) {             //生成材質球陣列              mats[i] = meshRenderers[i].sharedMaterial;            }         //---------------- 合併 Mesh -------------------------         //獲取自身和所有子物體中所有MeshFilter元件         MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();           CombineInstance[] combine = new CombineInstance[meshFilters.Length];            for (int i = 0; i < meshFilters.Length; i++) {             combine[i].mesh = meshFilters[i].sharedMesh;             //矩陣(Matrix)自身空間座標的點轉換成世界空間座標的點              combine[i].transform = meshFilters[i].transform.localToWorldMatrix;             meshFilters[i].gameObject.SetActive(false);         }          //為新的整體新建一個mesh         transform.GetComponent<MeshFilter>().mesh = new Mesh();          //合併Mesh. 第二個false引數, 表示並不合併為一個網格, 而是一個子網格列表         transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine, false);         transform.gameObject.SetActive(true);           //為合併後的新Mesh指定材質 ------------------------------         transform.GetComponent<MeshRenderer>().sharedMaterials = mats;      }          // Update is called once per frame     void Update () {              } }

5,執行效果如下。可以看到,Mesh和材質,都很好的得到了合併。坦克已經由零件,變成一個整體了! 但是,大家會發現這個模型,產生了一些變形!難道是這樣不對,或者是bug麼?不,其實不用擔心。這是因為前面用的Cube、Cylinder 等模擬底盤炮塔,手動調節了他們的縮放比例放造成的。如果以某個元件為根物體,那麼它的縮放比例,直接影響合併後生成的新物體。各個部件的縮放比都會按它走!。

也就是說,如果你想合併後不變形,就不要更改根物體的縮放比例。

參考:

關鍵函式,就是下面這個合併網格的函數了:

CombineMeshes(CombineInstance[]combine, boolmergeSubMeshes = true, booluseMatrices = true);

Unity官網,關於網格合併的例子:

http://docs.unity3d.com/ScriptReference/Mesh.CombineMeshes.html 

程式設計師俱樂部-Unity3d網格合併:

http://www.cxyclub.cn/n/54078/