Skip to content

Instantly share code, notes, and snippets.

@kalineh
Last active September 11, 2016 00:01
Show Gist options
  • Save kalineh/3368ea63b9a6d29aabd92847c2547038 to your computer and use it in GitHub Desktop.
Save kalineh/3368ea63b9a6d29aabd92847c2547038 to your computer and use it in GitHub Desktop.
Combine multiple meshes into single mesh
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
[InitializeOnLoad()]
class MeshCombinerHelperTag
{
static MeshCombinerHelperTag()
{
icon = EditorGUIUtility.ObjectContent(null, typeof(Mesh)).image;
EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyItem;
EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyItem;
EditorApplication.RepaintHierarchyWindow();
}
static Texture icon;
static void OnHierarchyItem(int instanceID, Rect instanceRect)
{
var obj = EditorUtility.InstanceIDToObject(instanceID);
var gameObject = obj as GameObject;
if (!gameObject)
return;
var combiner = gameObject.GetComponent<MeshCombinerHelper>();
if (!combiner)
return;
var width = 16;
var rightAlignedRect = new Rect(
instanceRect.xMax - width,
instanceRect.yMin,
width,
instanceRect.height + 1
);
GUI.Label(rightAlignedRect, icon);
}
}
#endif
public class MeshCombinerHelper
: MonoBehaviour
{
public void Start()
{
var meshFilters = GetComponentsInChildren<MeshFilter>();
var perMaterialCombines = new Dictionary<Material, List<CombineInstance>>();
var index = 0;
while (index < meshFilters.Length)
{
var meshRenderer = meshFilters[index].gameObject.GetComponent<MeshRenderer>();
var meshMaterial = meshRenderer.sharedMaterial;
if (!perMaterialCombines.ContainsKey(meshMaterial))
perMaterialCombines.Add(meshMaterial, new List<CombineInstance>());
var combines = perMaterialCombines[meshMaterial];
var combine = new CombineInstance();
combine.mesh = meshFilters[index].sharedMesh;
combine.transform = Matrix4x4.Inverse(transform.localToWorldMatrix) * meshFilters[index].transform.localToWorldMatrix;
combines.Add(combine);
meshFilters[index].gameObject.SetActive(false);
index++;
}
var count = 0;
foreach (var entry in perMaterialCombines)
{
var obj = gameObject;
if (count > 0)
{
obj = new GameObject(string.Format("MeshCombine{0}", count));
obj.transform.SetParent(transform);
obj.transform.ResetLocalTransforms();
}
var meshFilter = obj.AddComponent<MeshFilter>();
var meshRenderer = obj.AddComponent<MeshRenderer>();
meshRenderer.sharedMaterial = entry.Key;
meshFilter.mesh = new Mesh();
meshFilter.mesh.CombineMeshes(entry.Value.ToArray());
obj.SetActive(true);
count++;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment