12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- using UnityEngine;
- using System.Collections;
- /*
- Attach this script as a parent to some game objects. The script will then combine the meshes at startup.
- This is useful as a performance optimization since it is faster to render one big mesh than many small meshes. See the docs on graphics performance optimization for more info.
- Different materials will cause multiple meshes to be created, thus it is useful to share as many textures/material as you can.
- */
- [AddComponentMenu("Mesh/Combine Children")]
- public class CombineChildren : MonoBehaviour
- {
- /// Usually rendering with triangle strips is faster.
- /// However when combining objects with very low triangle counts, it can be faster to use triangles.
- /// Best is to try out which value is faster in practice.
- public bool generateTriangleStrips = true;
- /// This option has a far longer preprocessing time at startup but leads to better runtime performance.
- void Start()
- {
- Component[] filters = GetComponentsInChildren(typeof(MeshFilter));
- Matrix4x4 myTransform = transform.worldToLocalMatrix;
- Hashtable materialToMesh = new Hashtable();
- for (int i = 0; i < filters.Length; i++)
- {
- MeshFilter filter = (MeshFilter)filters[i];
- Renderer curRenderer = filters[i].GetComponent<Renderer>();
- MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance();
- instance.mesh = filter.sharedMesh;
- if (curRenderer != null && curRenderer.enabled && instance.mesh != null)
- {
- instance.transform = myTransform * filter.transform.localToWorldMatrix;
- Material[] materials = curRenderer.sharedMaterials;
- for (int m = 0; m < materials.Length; m++)
- {
- instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1);
- ArrayList objects = (ArrayList)materialToMesh[materials[m]];
- if (objects != null)
- {
- objects.Add(instance);
- }
- else
- {
- objects = new ArrayList();
- objects.Add(instance);
- materialToMesh.Add(materials[m], objects);
- }
- }
- curRenderer.enabled = false;
- }
- }
- foreach (DictionaryEntry de in materialToMesh)
- {
- ArrayList elements = (ArrayList)de.Value;
- MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance));
- // We have a maximum of one material, so just attach the mesh to our own game object
- if (materialToMesh.Count == 1)
- {
- // Make sure we have a mesh filter & renderer
- if (GetComponent(typeof(MeshFilter)) == null)
- gameObject.AddComponent(typeof(MeshFilter));
- if (!GetComponent<MeshRenderer>())
- gameObject.AddComponent<MeshRenderer>();
- MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter));
- filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips);
- GetComponent<Renderer>().material = (Material)de.Key;
- GetComponent<Renderer>().enabled = true;
- }
- // We have multiple materials to take care of, build one mesh / gameobject for each material
- // and parent it to this object
- else
- {
- GameObject go = new GameObject("Combined mesh");
- go.transform.parent = transform;
- go.transform.localScale = Vector3.one;
- go.transform.localRotation = Quaternion.identity;
- go.transform.localPosition = Vector3.zero;
- go.AddComponent(typeof(MeshFilter));
- go.AddComponent<MeshRenderer>();
- go.GetComponent<Renderer>().material = (Material)de.Key;
- MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter));
- filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips);
- }
- }
- }
- }
|