using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Multi-MaterialMeshMergeSnippet:MonoBehaviour
{
public void AdvancedMerge()
{
// All our children (and us)
MeshFilter[] filters = GetComponentsInChildren (false);
// All the meshes in our children (just a big list)
List materials = new List();
MeshRenderer[] renderers = GetComponentsInChildren (false); // <-- you can optimize this
foreach (MeshRenderer renderer in renderers)
{
if (renderer.transform == transform)
continue;
Material[] localMats = renderer.sharedMaterials;
foreach (Material localMat in localMats)
if (!materials.Contains (localMat))
materials.Add (localMat);
}
// Each material will have a mesh for it.
List submeshes = new List();
foreach (Material material in materials)
{
// Make a combiner for each (sub)mesh that is mapped to the right material.
List combiners = new List ();
foreach (MeshFilter filter in filters)
{
if (filter.transform == transform) continue;
// The filter doesn't know what materials are involved, get the renderer.
MeshRenderer renderer = filter.GetComponent (); // <-- (Easy optimization is possible here, give it a try!)
if (renderer == null)
{
Debug.LogError (filter.name + " has no MeshRenderer");
continue;
}
// Let's see if their materials are the one we want right now.
Material[] localMaterials = renderer.sharedMaterials;
for (int materialIndex = 0; materialIndex < localMaterials.Length; materialIndex++)
{
if (localMaterials [materialIndex] != material)
continue;
// This submesh is the material we're looking for right now.
CombineInstance ci = new CombineInstance();
ci.mesh = filter.sharedMesh;
ci.subMeshIndex = materialIndex;
ci.transform = Matrix4x4.identity;
combiners.Add (ci);
}
}
// Flatten into a single mesh.
Mesh mesh = new Mesh ();
mesh.CombineMeshes (combiners.ToArray(), true);
submeshes.Add (mesh);
}
// The final mesh: combine all the material-specific meshes as independent submeshes.
List finalCombiners = new List ();
foreach (Mesh mesh in submeshes)
{
CombineInstance ci = new CombineInstance ();
ci.mesh = mesh;
ci.subMeshIndex = 0;
ci.transform = Matrix4x4.identity;
finalCombiners.Add (ci);
}
Mesh finalMesh = new Mesh();
finalMesh.CombineMeshes (finalCombiners.ToArray(), false);
myMeshFilter.sharedMesh = finalMesh;
Debug.Log ("Final mesh has " + submeshes.Count + " materials.");
}
}