可直接调用的MergeUtils类 MergeUtils.MergeMesh会自动判断顶点是否超出合并最大顶点 然后分批 MergeUtils.MergeMesh3是直接合并
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
namespace OrcFramework.Game
{
public class MergeUtils
{
private static void MergeMesh2(GameObject parent, bool mergeSubMeshes = false)
{
MeshRenderer[] meshRenderers = parent.GetComponentsInChildren<MeshRenderer>();
Material[] materials = new Material[meshRenderers.Length];
for (int i = 0; i < meshRenderers.Length; i++)
{
materials[i] = meshRenderers[i].sharedMaterial;
}
MeshFilter[] meshFilters = parent.GetComponentsInChildren<MeshFilter>();
CombineInstance[] combineInstances = new CombineInstance[meshFilters.Length];
for (int i = 0; i < meshFilters.Length; i++)
{
combineInstances[i].mesh = meshFilters[i].sharedMesh;
combineInstances[i].transform = meshFilters[i].transform.localToWorldMatrix;
GameObject.DestroyImmediate(meshFilters[i].gameObject);
}
Mesh newMesh = new Mesh();
newMesh.CombineMeshes(combineInstances, mergeSubMeshes, true);
parent.AddComponent<MeshFilter>().sharedMesh = newMesh;
parent.AddComponent<MeshRenderer>().sharedMaterials = materials;
}
public static GameObject[] MergeMesh(GameObject parent, bool mergeAll = true, bool deleteChildren = false, bool mergeSubMeshes = false)
{
List<GameObject> list = new List<GameObject>();
int verts = 0;
Dictionary<int, GameObject> NewParent = new Dictionary<int, GameObject>();
MeshFilter[] meshFilters = parent.GetComponentsInChildren<MeshFilter>();
for (int i = 0; i < meshFilters.Length; i++)
{
verts += meshFilters[i].mesh.vertexCount;
if (NewParent.ContainsKey((verts / 65536) + 1))
{
meshFilters[i].transform.parent = NewParent[(verts / 65536) + 1].transform;
}
else
{
GameObject wx = new GameObject("Combine");
wx.transform.parent = parent.transform;
NewParent.Add((verts / 65536) + 1, wx);
meshFilters[i].transform.parent = NewParent[(verts / 65536) + 1].transform;
}
}
foreach (var item in NewParent)
{
list.Add(MergeUtils.MergeMesh3(item.Value, true, true));
}
if (deleteChildren)
{
for (int i = parent.transform.childCount - 1; i >= 0; i--)
{
if (parent.transform.GetChild(i).name != "Combine")
{
GameObject.Destroy(parent.transform.GetChild(i).gameObject);
}
}
}
return list.ToArray();
}
public static GameObject MergeMesh3(GameObject parent, bool mergeAll = true, bool deleteChildren = false, bool mergeSubMeshes = false)
{
MeshFilter[] meshFilters = parent.GetComponentsInChildren<MeshFilter>();
Dictionary<string, Material> materials = new Dictionary<string, Material>();
Dictionary<string, List<CombineInstance>> combines = new Dictionary<string, List<CombineInstance>>();
for (int i = 0; i < meshFilters.Length; i++)
{
CombineInstance combine = new CombineInstance();
combine.mesh = meshFilters[i].sharedMesh;
combine.transform = meshFilters[i].transform.localToWorldMatrix;
MeshRenderer renderer = meshFilters[i].GetComponent<MeshRenderer>();
if (renderer == null)
{
continue;
}
Material mat = renderer.sharedMaterial;
if (!materials.ContainsKey(mat.name))
{
materials.Add(mat.name, mat);
}
if (combines.ContainsKey(mat.name))
{
combines[mat.name].Add(combine);
}
else
{
List<CombineInstance> coms = new List<CombineInstance>();
coms.Add(combine);
combines[mat.name] = coms;
}
}
GameObject combineObj = new GameObject("Combine");
combineObj.transform.parent = parent.transform;
foreach (KeyValuePair<string, Material> mater in materials)
{
GameObject obj = new GameObject(mater.Key);
obj.transform.parent = combineObj.transform;
MeshFilter combineMeshFilter = obj.AddComponent<MeshFilter>();
combineMeshFilter.mesh = new Mesh();
combineMeshFilter.sharedMesh.CombineMeshes(combines[mater.Key].ToArray(), true, true);
Debug.LogError("网格定点数" + combineMeshFilter.sharedMesh.vertices);
MeshRenderer rend = obj.AddComponent<MeshRenderer>();
rend.sharedMaterial = mater.Value;
rend.shadowCastingMode = ShadowCastingMode.Off;
rend.receiveShadows = true;
}
if (mergeAll)
{
MergeMesh2(combineObj);
}
if (deleteChildren)
{
for (int i = parent.transform.childCount - 1; i >= 0; i--)
{
if (parent.transform.GetChild(i).name != "Combine")
{
GameObject.Destroy(parent.transform.GetChild(i).gameObject);
}
}
}
return combineObj;
}
public static GameObject MergeMesh4(GameObject parent, bool mergeAll = true, bool deleteChildren = false, bool mergeSubMeshes = false)
{
MeshFilter[] meshFilters = parent.GetComponentsInChildren<MeshFilter>();
Dictionary<string, Material> materials = new Dictionary<string, Material>();
Dictionary<string, List<CombineInstance>> combines = new Dictionary<string, List<CombineInstance>>();
for (int i = 0; i < meshFilters.Length; i++)
{
CombineInstance combine = new CombineInstance();
combine.mesh = meshFilters[i].sharedMesh;
combine.transform = meshFilters[i].transform.localToWorldMatrix;
MeshRenderer renderer = meshFilters[i].GetComponent<MeshRenderer>();
if (renderer == null)
{
continue;
}
Material mat = renderer.sharedMaterial;
if (!materials.ContainsKey(mat.name))
{
materials.Add(mat.name, mat);
}
if (combines.ContainsKey(mat.name))
{
combines[mat.name].Add(combine);
}
else
{
List<CombineInstance> coms = new List<CombineInstance>();
coms.Add(combine);
combines[mat.name] = coms;
}
}
GameObject combineObj = new GameObject("Combine");
combineObj.transform.parent = parent.transform;
foreach (KeyValuePair<string, Material> mater in materials)
{
GameObject obj = new GameObject(mater.Key);
obj.transform.parent = combineObj.transform;
MeshFilter combineMeshFilter = obj.AddComponent<MeshFilter>();
combineMeshFilter.mesh = new Mesh();
combineMeshFilter.sharedMesh.CombineMeshes(combines[mater.Key].ToArray(), true, true);
Debug.LogError("网格定点数" + combineMeshFilter.sharedMesh.vertices);
MeshRenderer rend = obj.AddComponent<MeshRenderer>();
rend.sharedMaterial = mater.Value;
rend.shadowCastingMode = ShadowCastingMode.Off;
rend.receiveShadows = true;
}
if (mergeAll)
{
MergeMesh2(combineObj);
}
if (deleteChildren)
{
for (int i = parent.transform.childCount - 1; i >= 0; i--)
{
if (parent.transform.GetChild(i).name != "Combine")
{
GameObject.Destroy(parent.transform.GetChild(i).gameObject);
}
}
}
return combineObj;
}
}
}
|