using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif namespace LunarCatsStudio.SuperCombiner { /// /// Submesh splitter. /// A helper class that offers possibility to split submeshes into separate meshes /// public class SubmeshSplitter { /// /// Extract a specific submesh at a given index from a mesh and return it as a new Mesh /// /// The mesh containing subMeshes /// The index of the subMesh to extract /// public static Mesh ExtractSubmesh(Mesh mesh, int index) { // Create the new mesh corresponding to the submesh at index i Mesh extractedSubMesh = CreateMeshFromSubmesh(mesh, new int[] { index }, index); // Return the extracted subMesh return extractedSubMesh; } /// /// Extract all the submeshes at given indexes into a separate mesh in a new GameObject /// /// /// List of ths submeshes indexes to extract /// Only used to name the new created mesh /// Returns a new GameObject with MeshRenderer and MeshFilter components. public static MeshRenderer SplitSubmeshes(MeshFilter meshFilter, int[] subMeshesIndex, int index) { if(subMeshesIndex.Length == 0) { Logger.Instance.AddLog("SuperCombiner", "Could not split submeshes of mesh " + meshFilter + " because indexes is null", Logger.LogLevel.LOG_ERROR); return null; } else if(meshFilter.sharedMesh == null) { Logger.Instance.AddLog("SuperCombiner", "Could not split submeshes of mesh " + meshFilter + " because it has no mesh", Logger.LogLevel.LOG_ERROR); return null; } Mesh mesh = meshFilter.sharedMesh; Material[] materials = meshFilter.GetComponent().sharedMaterials; Material[] splitMaterials = new Material[subMeshesIndex.Length]; for(int i=0; i(); } /// /// Extract all the submeshes at given indexes into a separate mesh in a new GameObject /// /// /// /// /// public static SkinnedMeshRenderer SplitSubmeshes(SkinnedMeshRenderer skinnedMesh, int[] subMeshesIndex, int index) { if (subMeshesIndex.Length == 0) { Logger.Instance.AddLog("SuperCombiner", "Could not split submeshes of mesh " + skinnedMesh + " because indexes is null", Logger.LogLevel.LOG_ERROR); return null; } else if (skinnedMesh.sharedMesh == null) { Logger.Instance.AddLog("SuperCombiner", "Could not split submeshes of mesh " + skinnedMesh + " because it has no mesh", Logger.LogLevel.LOG_ERROR); return null; } Mesh mesh = skinnedMesh.sharedMesh; Material[] materials = skinnedMesh.sharedMaterials; Material[] splitMaterials = new Material[subMeshesIndex.Length]; for (int i = 0; i < subMeshesIndex.Length; i++) { splitMaterials[i] = materials[subMeshesIndex[0]]; } // Create the new mesh corresponding to the submesh at index i Mesh newMesh = CreateMeshFromSubmesh(mesh, subMeshesIndex, index); // Generate target GameObject with MeshFilter and MeshRenderer GameObject go = GenerateGameObject(skinnedMesh.transform, true, skinnedMesh.gameObject.name, newMesh, splitMaterials); // Return the new meshRenderer component return go.GetComponent(); } /// /// Creates the mesh corresponding to a specific submesh. /// /// /// /// /// private static Mesh CreateMeshFromSubmesh(Mesh mesh, int[] subMeshesIndex, int index) { Vector3[] vertices = mesh.vertices; Vector3[] normals = mesh.normals; Vector4[] tangents = mesh.tangents; Color[] colors = mesh.colors; Vector2[] uvs = mesh.uv; Vector2[] uvs2 = mesh.uv2; Mesh newMesh = new Mesh(); newMesh.name = mesh.name + "_" + index; newMesh.vertices = vertices; newMesh.normals = normals; newMesh.tangents = tangents; newMesh.colors = colors; newMesh.uv = uvs; newMesh.uv2 = uvs2; newMesh.subMeshCount = subMeshesIndex.Length; for (int i=0; i /// Generates a new game object. /// /// /// /// /// /// /// private static GameObject GenerateGameObject(Transform parent, bool skinnedMesh, string name_p, Mesh newMesh_p, Material[] mat) { GameObject go = new GameObject(name_p); go.transform.SetParent(parent); go.transform.localPosition = Vector3.zero; go.transform.localRotation = Quaternion.identity; go.transform.localScale = Vector3.one; MeshFilter meshFilter = go.AddComponent(); meshFilter.mesh = newMesh_p; if(skinnedMesh) { SkinnedMeshRenderer meshRenderer = go.AddComponent(); meshRenderer.materials = mat; } else { MeshRenderer meshRenderer = go.AddComponent(); meshRenderer.materials = mat; } return go; } } }