hi,guys,glad to share a script!
put it in character,it can combine mesh and texture.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
public class CombineMesher : MonoBehaviour
{
void Start()
{
Combine(transform);
}
public Transform Combine(Transform root)
{
float startTime = Time.realtimeSinceStartup;
// The SkinnedMeshRenderers that will make up a character will be
// combined into one SkinnedMeshRenderers using one material.
// This will speed up rendering the resulting character.
// note:each SkinnedMeshRenderer must share a same material
List<CombineInstance> combineInstances = new List<CombineInstance>();
List<Material> materials = new List<Material>();
Material material = null;
List<Transform> bones = new List<Transform>();
Transform[] transforms = root.GetComponentsInChildren<Transform>();
List<Texture2D> textures = new List<Texture2D>();
int width = 0;
int height = 0;
int uvCount = 0;
List<Vector2[]> uvList = new List<Vector2[]>();
foreach (SkinnedMeshRenderer smr in root.GetComponentsInChildren<SkinnedMeshRenderer>())
{
if (material == null)
material = Instantiate(smr.sharedMaterial) as Material;
for (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++)
{
CombineInstance ci = new CombineInstance();
ci.mesh = smr.sharedMesh;
ci.subMeshIndex = sub;
combineInstances.Add(ci);
}
uvList.Add(smr.sharedMesh.uv);
uvCount += smr.sharedMesh.uv.Length;
if (smr.material.mainTexture != null)
{
textures.Add(smr.renderer.material.mainTexture as Texture2D);
width += smr.renderer.material.mainTexture.width;
height += smr.renderer.material.mainTexture.height;
}
// we need to recollect references to the bones we are using
foreach (Transform bone in smr.bones)
{
foreach (Transform transform in transforms)
{
if (transform.name != bone.name) continue;
bones.Add(transform);
break;
}
}
Object.Destroy(smr.gameObject);
}
// Obtain and configure the SkinnedMeshRenderer attached to
// the character base.
SkinnedMeshRenderer r = root.gameObject.GetComponent<SkinnedMeshRenderer>();
if (!r)
r = root.gameObject.AddComponent<SkinnedMeshRenderer>();
r.sharedMesh = new Mesh();
//only set mergeSubMeshes true will combine meshs into single submesh
r.sharedMesh.CombineMeshes(combineInstances.ToArray(), true, false);
r.bones = bones.ToArray();
r.material = material;
Texture2D skinnedMeshAtlas = new Texture2D(1024, 512);
Rect[] packingResult = skinnedMeshAtlas.PackTextures(textures.ToArray(), 0);
Vector2[] atlasUVs = new Vector2[uvCount];
//as combine textures into single texture,so need recalculate uvs
int j = 0;
for (int i = 0; i < uvList.Count; i++)
{
foreach (Vector2 uv in uvList[i])
{
atlasUVs[j].x = Mathf.Lerp(packingResult[i].xMin, packingResult[i].xMax, uv.x);
atlasUVs[j].y = Mathf.Lerp(packingResult[i].yMin, packingResult[i].yMax, uv.y);
j++;
}
}
r.material.mainTexture = skinnedMeshAtlas;
r.sharedMesh.uv = atlasUVs;
Debug.Log("combine meshes takes : " + (Time.realtimeSinceStartup - startTime) * 1000 + " ms");
return root;
}
}
Not perfect is it can’t combine normal texture.
enjoy it!
thanks