using UnityEngine;using System.Collections;using System.Collections.Generic;public class CombineMesh : MonoBehaviour{ void OnGUI() { if (GUI.Button(new Rect(0, 0, 200, 30), "CombineMeshes")) { CombineMeshes(); } } public void CombineMeshes() { SkinnedMeshRenderer[] smr = gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(); List<CombineInstance> combineInstances = new List<CombineInstance>(); List<Material> materials = new List<Material>(); List<Transform> bones = new List<Transform>(); for (int i = 0; i < smr.Length; i++) { materials.AddRange(smr[i].materials); bones.AddRange(smr[i].bones); // 收集待合并的對象信息 for (int k = 0; k < smr[i].sharedMesh.subMeshCount; k++) { CombineInstance ci = new CombineInstance(); ci.mesh = smr[i].sharedMesh; ci.subMeshIndex = k; combineInstances.Add(ci); } // 刪除原有模型的對象(如果有還原外觀的需求,也可以暫時將對象的活動狀態設置為false,代碼如下) // smr[i].gameObject.SetActive(false); Destroy(smr[i].gameObject); } // 創建新的SkinnedMeshRenderer,合并后的mesh數據都在該對象下 SkinnedMeshRenderer combinedSMR = gameObject.GetComponent<SkinnedMeshRenderer>(); if (combinedSMR == null) { combinedSMR = gameObject.AddComponent<SkinnedMeshRenderer>(); } combinedSMR.sharedMesh = new Mesh(); combinedSMR.bones = bones.ToArray(); combinedSMR.materials = materials.ToArray(); combinedSMR.rootBone = gameObject.transform; // 由于合并mesh的material數據不統一,因此第二項參數不能設置為true combinedSMR.sharedMesh.CombineMeshes(combineInstances.ToArray(), false, false); }}運行結果:
可以看到合并后人物的各個部件都合并到新創建的skinnenMeshRenderer下了,Unity Editor中Statistics中visible skinned meshes的數量也由9個變成了1個。總結分析性能方面會由于skinned mesh renderer的減少而減輕cpu的負擔,而在代碼中然而在導入模型資源時,需要將read/write enabled打鉤。
而該選項會增加內存的占用,mesh為了可以在代碼中進行修改,需要保留一份拷貝而駐留內存。官方的說明如下:Read/Write EnabledIf enabled, Mesh data is kept in memory so that a custom script can read and change it. Disabling this option saves memory, because Unity can unload a copy of Mesh data in the game. However, in certain cases when the Mesh is used with a Mesh Collider, this option must be enabled.
新聞熱點
疑難解答