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.
新闻热点
疑难解答