/// <summary> /// Combines selected gameobjects that have meshfilters to the lowest possible meshcount. /// </summary> private void Combine() { GameObject GO_Parent = Selection.gameObjects[0]; GameObject[] oldGameObjects = Selection.gameObjects; Vector3 oldPosition = new Vector3(GO_Parent.transform.position.x, GO_Parent.transform.position.y, GO_Parent.transform.position.z); // oldPositions.Clear(); // oldRotations.Clear(); // oldPositions = StoreOriginalPositions(oldGameObjects); // oldRotations = StoreOriginalQuaternions(oldGameObjects); Component[] filters = GetMeshFilters(); Matrix4x4 myTransform = GO_Parent.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>(); QT_MeshCombineUtility.MeshInstance instance = new QT_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); } } } } int nameCount = 1; //used for multimesh naming. //for each material found foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; QT_MeshCombineUtility.MeshInstance[] instances = (QT_MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(QT_MeshCombineUtility.MeshInstance)); GameObject go = new GameObject("Combined Mesh"); if (keepLayer) go.layer = GO_Parent.layer; // transforms should be zeroed out, then reset when we place the new object em. go.transform.localScale = Vector3.one; go.transform.localRotation = GO_Parent.transform.localRotation; go.transform.localPosition = Vector3.zero; go.transform.position = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent<MeshRenderer>(); go.GetComponent<Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.sharedMesh = QT_MeshCombineUtility.Combine(instances, false); // filter.GetComponent<Renderer>().receiveShadows = receiveShadows; // filter.GetComponent<Renderer>().castShadows = castShadows; go.isStatic = isStatic; if (isLightmapped) Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh); if (addMeshCollider) go.AddComponent<MeshCollider>(); //add the new object to our list. newObjects.Add(go); } if (destroyAfterOptimized) { for (int x = 0; x < oldGameObjects.Length; x++) DestroyImmediate(oldGameObjects[x]); } //if we found unique materials, make sure we name the GO's properly. if (newObjects.Count > 1) { for (int x = 0; x < newObjects.Count; x++) { if (x > 0) newObjects[x].name = newName + nameCount; else newObjects[0].name = newName; nameCount++; newObjects[x].transform.position = oldPosition; } } else { newObjects[0].name = newName; newObjects[0].transform.position = oldPosition; } if (createParentGO) { GameObject p = new GameObject(newName); p.transform.position = oldPosition; foreach (GameObject g in newObjects) g.transform.parent = p.transform; } }
/// <summary> /// Combines selected gameobjects that have meshfilters to the lowest possible meshcount. /// </summary> private void Combine() { GameObject GO_Parent = Selection.gameObjects[0]; GameObject[] oldGameObjects = Selection.gameObjects; Vector3 oldPosition = new Vector3(GO_Parent.transform.position.x, GO_Parent.transform.position.y, GO_Parent.transform.position.z); // oldPositions.Clear(); // oldRotations.Clear(); // oldPositions = StoreOriginalPositions(oldGameObjects); // oldRotations = StoreOriginalQuaternions(oldGameObjects); Component[] filters = GetMeshFilters(); Matrix4x4 myTransform = GO_Parent.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>(); QT_MeshCombineUtility.MeshInstance instance = new QT_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); } } } } int nameCount = 1; //used for multimesh naming. //for each material found foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; QT_MeshCombineUtility.MeshInstance[] instances = (QT_MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(QT_MeshCombineUtility.MeshInstance)); GameObject go = new GameObject("Combined Mesh"); if (keepLayer) { go.layer = GO_Parent.layer; } // transforms should be zeroed out, then reset when we place the new object em. go.transform.localScale = Vector3.one; go.transform.localRotation = GO_Parent.transform.localRotation; go.transform.localPosition = Vector3.zero; go.transform.position = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent <MeshRenderer>(); go.GetComponent <Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.sharedMesh = QT_MeshCombineUtility.Combine(instances, false); // filter.GetComponent<Renderer>().receiveShadows = receiveShadows; // filter.GetComponent<Renderer>().castShadows = castShadows; go.isStatic = isStatic; if (isLightmapped) { Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh); } if (addMeshCollider) { go.AddComponent <MeshCollider>(); } //add the new object to our list. newObjects.Add(go); } if (destroyAfterOptimized) { for (int x = 0; x < oldGameObjects.Length; x++) { DestroyImmediate(oldGameObjects[x]); } } //if we found unique materials, make sure we name the GO's properly. if (newObjects.Count > 1) { for (int x = 0; x < newObjects.Count; x++) { if (x > 0) { newObjects[x].name = newName + nameCount; } else { newObjects[0].name = newName; } nameCount++; newObjects[x].transform.position = oldPosition; } } else { newObjects[0].name = newName; newObjects[0].transform.position = oldPosition; } if (createParentGO) { GameObject p = new GameObject(newName); p.transform.position = oldPosition; foreach (GameObject g in newObjects) { g.transform.parent = p.transform; } } }