Reputation: 3562
I have three meshes A, B and C. Each mesh has it's own material and consists of single subMesh. Now, I want to create a new mesh which will contain, for example, 10 instances of each (A, B and C) mesh and it will consist of 3 subMeshes, i.e. one subMesh for all elements of each type.
I use "Mesh.CombineMeshes(...)" for this purpose, but it combines all meshes into one subMesh or creates subMesh for every element (i.e. 30 subMeshes in my case). Both results are unacceptable for me.
Upvotes: 3
Views: 8011
Reputation: 2943
You can first combine all meshes of type A to mesh 1, all meshes of type B to mesh 2 and all meshes of type C to mesh 3, with mergeSubMeshes = true
.
Then you simply combine meshes 1, 2, and 3 into single mesh, with mergeSubMeshes = false
, resulting with a single mesh with 3 sub meshes, each sub mesh built of meshes of single type, as you wanted.
MeshFilter.sharedMesh can be used to group your meshes by type.
Here is the code:
Mesh CombineMeshes(MeshFilter[] meshes) {
// Key: shared mesh instance ID, Value: arguments to combine meshes
var helper = new Dictionary<int, List<CombineInstance>>();
// Build combine instances for each type of mesh
foreach (var m in meshes) {
List<CombineInstance> tmp;
if (!helper.TryGetValue(m.sharedMesh.GetInstanceID(), out tmp)) {
tmp = new List<CombineInstance>();
helper.Add(m.sharedMesh.GetInstanceID(), tmp);
}
var ci = new CombineInstance();
ci.mesh = m.sharedMesh;
ci.transform = m.transform.localToWorldMatrix;
tmp.Add(ci);
}
// Combine meshes and build combine instance for combined meshes
var list = new List<CombineInstance>();
foreach (var e in helper) {
var m = new Mesh();
m.CombineMeshes(e.Value.ToArray());
var ci = new CombineInstance();
ci.mesh = m;
list.Add(ci);
}
// And now combine everything
var result = new Mesh();
result.CombineMeshes(list.ToArray(), false, false);
// It is a good idea to clean unused meshes now
foreach (var m in list) {
Destroy(m.mesh);
}
return result;
}
Upvotes: 5