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();
}
}
}