using System; using System.Collections.Generic; using NaughtyAttributes; using UnityEditor; using UnityEngine; namespace Util.Mesh { public class MeshCombinerStart : MonoBehaviour { [SerializeField] private MeshCombiner meshCombiner; private void Start() { meshCombiner.CombineMeshes(true); } private int GetTotalPolygons(Transform parent, MeshCombiner combiner) { MeshFilter[] meshFilters = combiner.GetMeshFiltersToCombine(); MeshRenderer[] meshRenderers = new MeshRenderer[meshFilters.Length]; meshRenderers[0] = GetComponent(); // Our (parent) MeshRenderer. List uniqueMaterialsList = new List(); for (int i = 0; i < meshFilters.Length - 1; i++) { meshRenderers[i + 1] = meshFilters[i + 1].GetComponent(); if (meshRenderers[i + 1] != null) { Material[] materials = meshRenderers[i + 1].sharedMaterials; // Get all Materials from child Mesh. for (int j = 0; j < materials.Length; j++) { if (!uniqueMaterialsList .Contains(materials[j])) // If Material doesn't exists in the list then add it. { uniqueMaterialsList.Add(materials[j]); } } } } List finalMeshCombineInstancesList = new List(); long verticesLength = 0; for (int i = 0; i < uniqueMaterialsList.Count; i++) // Create each Mesh (submesh) from Meshes with the same Material. { List submeshCombineInstancesList = new List(); for (int j = 0; j < meshFilters.Length - 1; j++) // Get only childeren Meshes (skip our Mesh). { if (meshRenderers[j + 1] != null) { Material[] submeshMaterials = meshRenderers[j + 1].sharedMaterials; // Get all Materials from child Mesh. for (int k = 0; k < submeshMaterials.Length; k++) { if (uniqueMaterialsList[i] == submeshMaterials[k]) { CombineInstance combineInstance = new CombineInstance(); combineInstance.subMeshIndex = k; // Mesh may consist of smaller parts - submeshes. combineInstance.mesh = meshFilters[j + 1].sharedMesh; combineInstance.transform = meshFilters[j + 1].transform.localToWorldMatrix; submeshCombineInstancesList.Add(combineInstance); verticesLength += combineInstance.mesh.vertices.Length; } } } } } return (int)verticesLength; } [Button("Get Value")] public void GetValue() { if (meshCombiner == null) meshCombiner = GetComponent(); var val = GetTotalPolygons(transform,meshCombiner); if (val <= MeshCombiner.Mesh16BitBufferVertexLimit) Debug.Log("Mesh will created with "+val+" vertices"); else Debug.Log("Mesh will created with "+val+" over 65535 vertices."); } [Button("Combine")] public void Combine() { if (meshCombiner == null) meshCombiner = GetComponent(); meshCombiner.CreateMultiMaterialMesh = true; meshCombiner.GenerateUVMap = true; meshCombiner.CombineMeshes(true); } [Button("Split all Meshes")] public void SplitMeshes() { var allMeshes = GetComponentsInChildren(); foreach (var meshes in allMeshes) { SplitMesh(meshes); } Debugger.Logger($"Splited {gameObject.name}"); } public void SplitMesh(MeshRenderer mesh) { MeshFilter mf = mesh.GetComponent(); MeshRenderer mr = mesh.GetComponent(); if (mf == null || mr == null) return; UnityEngine.Mesh originalMesh = mf.sharedMesh; if (originalMesh == null || originalMesh.subMeshCount < 1) return; int subMeshCount = originalMesh.subMeshCount; var preset = new GameObject(mesh.name,typeof(MeshFilter), typeof(MeshRenderer)); for (int i = 0; i < subMeshCount; i++) { UnityEngine.Mesh newMesh = new UnityEngine.Mesh { vertices = originalMesh.vertices, normals = originalMesh.normals, uv = originalMesh.uv, triangles = originalMesh.GetTriangles(i) }; var part = Instantiate(preset, mesh.transform); part.GetComponent().mesh = newMesh; part.GetComponent().sharedMaterial = (i < mr.sharedMaterials.Length) ? mr.sharedMaterials[i] : mr.sharedMaterial; } DestroyImmediate(preset); // DestroyImmediate(mesh)?; } [Button("Center Mesh")] void CenterMeshPivot() { UnityEngine.Mesh mesh = GetComponent().sharedMesh; Vector3 center = mesh.bounds.center; Vector3[] vertices = mesh.vertices; for (int i = 0; i < vertices.Length; i++) { vertices[i] -= center; } mesh.vertices = vertices; mesh.RecalculateBounds(); mesh.RecalculateNormals(); transform.position += center; } } }