Created
June 15, 2024 13:26
-
-
Save Wolfos/2996fe475ae546f3a75459c84b503e68 to your computer and use it in GitHub Desktop.
Static mesh combiner for Unity. Very basic. Ignores meshes that have multiple materials.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using Sirenix.OdinInspector; | |
using UnityEngine; | |
using UnityEngine.Rendering; | |
public class MeshCombiner : MonoBehaviour | |
{ | |
[SerializeField, HideInInspector] private MeshRenderer[] meshRenderers; | |
[SerializeField, HideInInspector] private List<GameObject> combinedObjects; | |
[Button("Combine meshes")] | |
public void CombineMeshes() | |
{ | |
UndoCombine(); | |
meshRenderers = GetComponentsInChildren<MeshRenderer>().Where(m => m.enabled && m.gameObject.activeInHierarchy && m.gameObject.isStatic).ToArray(); | |
Dictionary<Material, List<MeshFilter>> filtersByMaterial = new(); | |
foreach (var meshRenderer in meshRenderers) | |
{ | |
if(meshRenderer.sharedMaterials.Length > 1) continue; | |
var material = meshRenderer.sharedMaterial; | |
if (filtersByMaterial.ContainsKey(material) == false) | |
{ | |
filtersByMaterial.Add(material, new()); | |
} | |
var list = filtersByMaterial[material]; | |
list.Add(meshRenderer.GetComponent<MeshFilter>()); | |
} | |
Matrix4x4 GetParentRelativeMatrix(Transform childObject, Transform parentObject) | |
{ | |
return parentObject.worldToLocalMatrix * childObject.localToWorldMatrix; | |
} | |
foreach (var kvp in filtersByMaterial) | |
{ | |
var material = kvp.Key; | |
var meshFilters = kvp.Value; | |
var combine = new CombineInstance[meshFilters.Count]; | |
for (var i = 0; i < combine.Length; i++) | |
{ | |
combine[i].mesh = meshFilters[i].sharedMesh; | |
combine[i].transform = GetParentRelativeMatrix(meshFilters[i].transform, transform); | |
meshFilters[i].GetComponent<MeshRenderer>().enabled = false; | |
} | |
var combinedMesh = new Mesh(); | |
combinedMesh.indexFormat = IndexFormat.UInt32; | |
combinedMesh.CombineMeshes(combine); | |
var go = new GameObject(material.name); | |
go.transform.parent = transform; | |
go.transform.localPosition = Vector3.zero; | |
go.transform.localRotation = Quaternion.identity; | |
go.transform.localScale = Vector3.one; | |
go.AddComponent<MeshFilter>().sharedMesh = combinedMesh; | |
go.AddComponent<MeshRenderer>().material = material; | |
combinedObjects.Add(go); | |
} | |
} | |
[Button("Undo")] | |
public void UndoCombine() | |
{ | |
if (meshRenderers == null) return; | |
foreach (var meshRenderer in meshRenderers) | |
{ | |
meshRenderer.enabled = true; | |
} | |
foreach (var go in combinedObjects) | |
{ | |
DestroyImmediate(go); | |
} | |
combinedObjects.Clear(); | |
meshRenderers = null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment