using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class CombineSkinMesh : MonoBehaviour { public SkinnedMeshRenderer Body; private Transform[] childTransforms = null; public SkinnedMeshRenderer[] OldClothes = new SkinnedMeshRenderer[3]; public SkinnedMeshRenderer[] Clothes = new SkinnedMeshRenderer[3]; private Dictionary BeforeClothDic = new Dictionary(); private Dictionary EquipClothDic = new Dictionary(); void Start() { childTransforms = gameObject.GetComponentsInChildren(false); Debug.Log("childTransforms : " + childTransforms.Length); //Transform shangyi = transform.Find("FE_Top001"); //Transform xiazhuang = transform.Find("FE_BTM001"); //OrginClothDic.Add(ClothType.Shangyi, shangyi.GetComponent()); //OrginClothDic.Add(ClothType.Xiazhuang, xiazhuang.GetComponent()); } void Update() { } public void ChangeCloth(ClothType _type, GameObject _skin) { if(EquipClothDic.TryGetValue(_type, out var value)) { BeforeClothDic[_type] = value; } else { BeforeClothDic[_type] = null; } ; EquipClothDic[_type] = _skin; CustomRoleUtility.ChangeCloth(BeforeClothDic[_type], EquipClothDic[_type],childTransforms); //StopAllCoroutines(); //var wrap = _skin.transform.GetChild(0).gameObject.GetOrAddComponent(); var wrap = _skin.GetComponentInChildren().gameObject.GetOrAddComponent(); wrap.target = Body.GetComponent(); StartCoroutine(WrapModel(wrap)); } public IEnumerator WrapModel(MegaWrap _wrap) { yield return new WaitForSeconds(0.5f); //_wrap.Attach(_wrap.target); //_wrap.Attach(); } public void StartCombine() { Debug.Log("Combine"); childTransforms = gameObject.GetComponentsInChildren(false); for (int i = 0; i < 3; i++) { //CustomRoleUtility.ChangeCloth(OldClothes[i], Clothes[i], childTransforms); } } /// /// Only for merge materials. /// private const int COMBINE_TEXTURE_MAX = 512; private const string COMBINE_DIFFUSE_TEXTURE = "_MainTex"; /// /// Combine SkinnedMeshRenderers together and share one skeleton. /// Merge materials will reduce the drawcalls, but it will increase the size of memory. /// /// combine meshes to this skeleton(a gameobject) /// meshes need to be merged /// merge materials or not public void CombineObject(GameObject skeleton, SkinnedMeshRenderer[] meshes, bool combine = false) { // 收集所有关于skeleton的骨骼 List transforms = new List(); transforms.AddRange(skeleton.GetComponentsInChildren(true)); List materials = new List();//材质 List combineInstances = new List();//网格 List bones = new List();//骨骼 // 下面的信息只用来合并材质(bool combine = true) List oldUV = null; Material newMaterial = null; Texture2D newDiffuseTex = null; // 收集网格部分信息 for (int i = 0; i < meshes.Length; i++) { SkinnedMeshRenderer smr = meshes[i]; // 收集材质 materials.AddRange(smr.sharedMaterials); // 收集网格 for (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++) { CombineInstance ci = new CombineInstance(); ci.mesh = smr.sharedMesh; ci.subMeshIndex = sub; combineInstances.Add(ci); } // 收集骨骼 for (int j = 0; j < smr.bones.Length; j++) { int tBase = 0; for (tBase = 0; tBase < transforms.Count; tBase++) { if (smr.bones[j].name.Equals(transforms[tBase].name)) { bones.Add(transforms[tBase]); break; } } } } // 合并材质 if (combine) { newMaterial = new Material(Shader.Find("Mobile/Diffuse")); oldUV = new List(); // 合并贴图 List Textures = new List(); for (int i = 0; i < materials.Count; i++) { Textures.Add(materials[i].GetTexture(COMBINE_DIFFUSE_TEXTURE) as Texture2D); } newDiffuseTex = new Texture2D(COMBINE_TEXTURE_MAX, COMBINE_TEXTURE_MAX, TextureFormat.RGBA32, true); Rect[] uvs = newDiffuseTex.PackTextures(Textures.ToArray(), 0); newMaterial.mainTexture = newDiffuseTex; // 重置uv贴图 Vector2[] uva, uvb; for (int j = 0; j < combineInstances.Count; j++) { uva = (Vector2[])(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 oldSKinned = skeleton.GetComponent(); if (oldSKinned != null) { GameObject.DestroyImmediate(oldSKinned); } SkinnedMeshRenderer r = skeleton.AddComponent(); r.sharedMesh = new Mesh(); r.sharedMesh.CombineMeshes(combineInstances.ToArray(), combine, false);// 合并网格 r.sharedMesh.name = "newMesh"; r.bones = bones.ToArray();// 使用新骨骼 if (combine) { r.material = newMaterial; for (int i = 0; i < combineInstances.Count; i++) { combineInstances[i].mesh.uv = oldUV[i]; } } else { r.materials = materials.ToArray(); } } }