合并SkinnedMeshRender实现换装
using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; public class CombineSkinnedMeshMananger { private const int MAXTEXTURESIZE = 512; public void CombineSkinnedMeshRender(GameObject instance, SkinnedMeshRenderer[] skinnedMeshRenderers,bool isCombine =false) { if (instance == null) { return; } List<Transform> transforms = new List<Transform>(); transforms.AddRange(instance.GetComponentsInChildren<Transform>(true)); List<CombineInstance> combineInstances = new List<CombineInstance>(); //网格 List<Transform> bones = new List<Transform>(); //骨骼 List<Material> materials= new List<Material>(); //材质 if (skinnedMeshRenderers == null || skinnedMeshRenderers.Length == 0) { return; } for (int i = 0; i < skinnedMeshRenderers.Length; i++) { SkinnedMeshRenderer smr = skinnedMeshRenderers[i]; //收集材质 materials.AddRange(smr.materials); //收集网格 for (int j = 0; j < smr.sharedMesh.subMeshCount; j++) { CombineInstance combineInstance = new CombineInstance(); combineInstance.mesh = smr.sharedMesh; combineInstance.subMeshIndex = j; combineInstances.Add(combineInstance); } //收集骨骼 for (int j = 0; j < smr.bones.Length; j++) { for (int k = 0; k < transforms.Count; k++) { if (smr.bones[j].name.Equals(transforms[k].name)) { bones.Add(transforms[k]); break; } } } } List<Vector2[]> oldUV = null; Material newMaterila = null; Texture2D newDiffuseTex = null; //合并材质 if (isCombine) { //这里材质类型和没有合并之前的材质类型要保持一直 newMaterila = new Material(Shader.Find("Mobile/Diffuse")); oldUV = new List<Vector2[]>(); //合并贴图 List<Texture2D> textures = new List<Texture2D>(); for (int i = 0; i < materials.Count; i++) { textures.Add(materials[i].GetTexture("_MainTex") as Texture2D); } newDiffuseTex = new Texture2D(MAXTEXTURESIZE,MAXTEXTURESIZE,TextureFormat.RGBA32,true); Rect[] uvs = newDiffuseTex.PackTextures(textures.ToArray(), 0); newMaterila.mainTexture = newDiffuseTex; //重置UV ??? Vector2[] uva, uvb; for (int j = 0; j < combineInstances.Count; j++) { uva = combineInstances[j].mesh.uv; uvb = new Vector2[uva.Length]; for (int k = 0; k < uva.Length; k++) { uvb[k] = new Vector2((uva[k].x * uvs[j].width) + uvs[j].x, (uva[k].y * uvs[j].height) + uvs[j].y); } oldUV.Add(combineInstances[j].mesh.uv); combineInstances[j].mesh.uv = uvb; } } //重新绑定SkinnedMeshRenderer SkinnedMeshRenderer oldSkinnedMeshRenderer = instance.GetComponent<SkinnedMeshRenderer>(); if (oldSkinnedMeshRenderer != null) { GameObject.DestroyImmediate(oldSkinnedMeshRenderer); } SkinnedMeshRenderer skinnedMeshRenderer = instance.AddComponent<SkinnedMeshRenderer>(); skinnedMeshRenderer.sharedMesh = new Mesh(); skinnedMeshRenderer.sharedMesh.CombineMeshes(combineInstances.ToArray(), isCombine,false); skinnedMeshRenderer.bones = bones.ToArray(); if (isCombine) { skinnedMeshRenderer.material = newMaterila; //??? 这里为啥又换回来了 for (int i = 0 ; i < combineInstances.Count ; i ++) { combineInstances[i].mesh.uv = oldUV[i]; } } else { skinnedMeshRenderer.materials = materials.ToArray(); } } }