using System.Collections; using System.Collections.Generic; using System.IO; using GK; using UnityEditor; using UnityEngine; using UnityEngine.Rendering; namespace Net.Project.B.Bounds { public class UnityMeshColliderCovertExplorer { [MenuItem("Tools/Export GameObjects to Convex Mesh")] private static void ExportConvex() { var go = Selection.activeGameObject; if (!go) { Debug.LogError("No object selected"); return; } var nonConvexMesh = GetMesh(go); var hullCalculator = new ConvexHullCalculator(); var allVertices = new List(); var allTriangles = new List(); var allNormals = new List(); var vertices = new List(); nonConvexMesh.GetVertices(vertices); hullCalculator.GenerateHull(vertices, true, ref allVertices, ref allTriangles, ref allNormals); var newMesh = new Mesh(); newMesh.SetVertices(allVertices); newMesh.SetTriangles(allTriangles, 0); newMesh.SetNormals(allNormals); var newGo = new GameObject("Combined Mesh"); newGo.AddComponent().mesh = newMesh; newGo.AddComponent(); } [MenuItem("Tools/Export GameObjects to Non Convex Mesh")] private static void ExportNonConvex() { var go = Selection.activeGameObject; if (!go) { Debug.LogError("No object selected"); return; } var newMesh = GetMesh(go); var newGo = new GameObject("Combined Mesh"); newGo.AddComponent().mesh = newMesh; newGo.AddComponent(); } private static Mesh GetMesh(GameObject go) { var hullCalculator = new ConvexHullCalculator(); var combineInstances = new List(); foreach (var collider in go.GetComponentsInChildren()) { switch (collider) { case BoxCollider boxCollider: { var mesh = CreateBoxMesh(boxCollider); combineInstances.Add(new CombineInstance() { mesh = mesh, transform = collider.transform.localToWorldMatrix }); } break; case MeshCollider meshCollider: { var allVertices = new List(); var allTriangles = new List(); var allNormals = new List(); var mesh = meshCollider.sharedMesh; var vertices = new List(); for (var index = 0; index < vertices.Count; index++) { var vertex = vertices[index]; vertex = meshCollider.transform.TransformPoint(vertex); vertices[index] = vertex; } mesh.GetVertices(vertices); hullCalculator.GenerateHull(vertices, true, ref allVertices, ref allTriangles, ref allNormals); mesh = new Mesh { indexFormat = IndexFormat.UInt32 }; mesh.SetVertices(allVertices); mesh.SetTriangles(allTriangles, 0); mesh.SetNormals(allNormals); combineInstances.Add(new CombineInstance() { mesh = mesh, transform = meshCollider.transform.localToWorldMatrix }); } break; } } var newMesh = new Mesh(); newMesh.CombineMeshes(combineInstances.ToArray()); return newMesh; } private static Mesh CreateBoxMesh(BoxCollider box) { var size = box.size; var center = box.center; var mesh = new Mesh(); Vector3[] vertices = { // Bottom new Vector3(-1, -1, -1), new Vector3( 1, -1, -1), new Vector3( 1, -1, 1), new Vector3(-1, -1, 1), // Top new Vector3(-1, 1, -1), new Vector3( 1, 1, -1), new Vector3( 1, 1, 1), new Vector3(-1, 1, 1), }; int[] triangles = { // Bottom 0, 2, 1, 0, 3, 2, // Top 4, 5, 6, 4, 6, 7, // Front 0, 1, 5, 0, 5, 4, // Back 2, 3, 7, 2, 7, 6, // Left 3, 0, 4, 3, 4, 7, // Right 1, 2, 6, 1, 6, 5, }; // Scale and offset vertices according to size and center for (int i = 0; i < vertices.Length; i++) { vertices[i] = Vector3.Scale(vertices[i], size * 0.5f) + center; } mesh.vertices = vertices; mesh.triangles = triangles; mesh.RecalculateNormals(); mesh.RecalculateBounds(); return mesh; } } }