Unity SkinMesh之如何分割SubMesh
可参考:http://answers.unity3d.com/questions/1213025/separating-submeshes-into-unique-meshes.html
代码如下:
1 using UnityEditor; 2 using UnityEngine; 3 using System.Collections.Generic; 4 5 public class SubmeshSplitter 6 { 7 //http://answers.unity3d.com/questions/1213025/separating-submeshes-into-unique-meshes.html 8 [MenuItem("美术/Submesh Splitter", false, 7002)] 9 public static void BuildWindowsAssetBundle() 10 { 11 GameObject[] objects = Selection.gameObjects; 12 for (int i = 0; i < objects.Length; i++) 13 { 14 ProcessGameObject(objects[i]); 15 } 16 Debug.Log("Done splitting meshes into submeshes! " + System.DateTime.Now); 17 } 18 19 public class MeshFromSubmesh 20 { 21 public Mesh mesh; 22 public int id; // Represent the ID of the sub mesh from with the new 'mesh' has been created 23 } 24 25 private static void ProcessGameObject(GameObject go) 26 { 27 SkinnedMeshRenderer meshRendererComponent = go.GetComponent<SkinnedMeshRenderer>(); 28 if (!meshRendererComponent) 29 { 30 Debug.LogError("MeshRenderer null for '" + go.name + "'!"); 31 return; 32 } 33 Mesh mesh = go.GetComponent<SkinnedMeshRenderer>().sharedMesh; 34 if (!mesh) 35 { 36 Debug.LogError("Mesh null for '" + go.name + "'!"); 37 return; 38 } 39 List<MeshFromSubmesh> meshFromSubmeshes = GetAllSubMeshAsIsolatedMeshes(mesh); 40 if (meshFromSubmeshes == null || meshFromSubmeshes.Count == 0) 41 { 42 Debug.LogError("List<MeshFromSubmesh> empty or null for '" + go.name + "'!"); 43 return; 44 } 45 string goName = go.name; 46 for (int i = 0; i < meshFromSubmeshes.Count; i++) 47 { 48 string meshFromSubmeshName = goName + "_sub_" + i; 49 GameObject meshFromSubmeshGameObject = new GameObject(); 50 meshFromSubmeshGameObject.name = meshFromSubmeshName; 51 meshFromSubmeshGameObject.transform.SetParent(meshRendererComponent.transform); 52 meshFromSubmeshGameObject.transform.localPosition = Vector3.zero; 53 meshFromSubmeshGameObject.transform.localRotation = Quaternion.identity; 54 SkinnedMeshRenderer meshFromSubmeshMeshRendererComponent = meshFromSubmeshGameObject.AddComponent<SkinnedMeshRenderer>(); 55 meshFromSubmeshMeshRendererComponent.sharedMesh = meshFromSubmeshes[i].mesh; 56 // Don't forget to save the newly created mesh in the asset database (on disk) 57 var mehs_path = AssetDatabase.GetAssetPath(mesh); 58 string path = mehs_path + meshFromSubmeshName + ".asset"; 59 AssetDatabase.CreateAsset(meshFromSubmeshes[i].mesh, path); 60 Debug.Log("Created: " + path); 61 if (meshRendererComponent != null) 62 { 63 // To use the same mesh renderer properties of the initial mesh 64 EditorUtility.CopySerialized(meshRendererComponent, meshFromSubmeshMeshRendererComponent); 65 // We just need the only one material used by the sub mesh in its renderer 66 Material material = meshFromSubmeshMeshRendererComponent.sharedMaterials[meshFromSubmeshes[i].id]; 67 meshFromSubmeshMeshRendererComponent.sharedMaterials = new[] { material }; 68 } 69 var newMesh = AssetDatabase.LoadAssetAtPath<Mesh>(path); 70 meshFromSubmeshMeshRendererComponent.sharedMesh = newMesh; 71 } 72 } 73 74 private static List<MeshFromSubmesh> GetAllSubMeshAsIsolatedMeshes(Mesh mesh) 75 { 76 List<MeshFromSubmesh> meshesToReturn = new List<MeshFromSubmesh>(); 77 if (!mesh) 78 { 79 Debug.LogError("No mesh passed into GetAllSubMeshAsIsolatedMeshes!"); 80 return meshesToReturn; 81 } 82 int submeshCount = mesh.subMeshCount; 83 if (submeshCount < 2) 84 { 85 Debug.LogError("Only " + submeshCount + " submeshes in mesh passed to GetAllSubMeshAsIsolatedMeshes"); 86 return meshesToReturn; 87 } 88 MeshFromSubmesh m1; 89 for (int i = 0; i < submeshCount; i++) 90 { 91 m1 = new MeshFromSubmesh(); 92 m1.id = i; 93 m1.mesh = mesh.GetSubmesh(i); 94 meshesToReturn.Add(m1); 95 } 96 return meshesToReturn; 97 } 98 } 99 100 public static class MeshExtension 101 { 102 private class Vertices 103 { 104 List<Vector3> verts = null; 105 List<Vector2> uv1 = null; 106 List<Vector2> uv2 = null; 107 List<Vector2> uv3 = null; 108 List<Vector2> uv4 = null; 109 List<Vector3> normals = null; 110 List<Vector4> tangents = null; 111 List<Color32> colors = null; 112 List<BoneWeight> boneWeights = null; 113 public List<Matrix4x4> bindposes = null; 114 115 public Vertices() 116 { 117 verts = new List<Vector3>(); 118 } 119 public Vertices(Mesh aMesh) 120 { 121 verts = CreateList(aMesh.vertices); 122 uv1 = CreateList(aMesh.uv); 123 uv2 = CreateList(aMesh.uv2); 124 uv3 = CreateList(aMesh.uv3); 125 uv4 = CreateList(aMesh.uv4); 126 normals = CreateList(aMesh.normals); 127 tangents = CreateList(aMesh.tangents); 128 colors = CreateList(aMesh.colors32); 129 boneWeights = CreateList(aMesh.boneWeights); 130 bindposes = CreateList(aMesh.bindposes); 131 } 132 133 private List<T> CreateList<T>(T[] aSource) 134 { 135 if (aSource == null || aSource.Length == 0) 136 return null; 137 return new List<T>(aSource); 138 } 139 private void Copy<T>(ref List<T> aDest, List<T> aSource, int aIndex) 140 { 141 if (aSource == null) 142 return; 143 if (aDest == null) 144 aDest = new List<T>(); 145 aDest.Add(aSource[aIndex]); 146 } 147 public int Add(Vertices aOther, int aIndex) 148 { 149 int i = verts.Count; 150 Copy(ref verts, aOther.verts, aIndex); 151 Copy(ref uv1, aOther.uv1, aIndex); 152 Copy(ref uv2, aOther.uv2, aIndex); 153 Copy(ref uv3, aOther.uv3, aIndex); 154 Copy(ref uv4, aOther.uv4, aIndex); 155 Copy(ref normals, aOther.normals, aIndex); 156 Copy(ref tangents, aOther.tangents, aIndex); 157 Copy(ref colors, aOther.colors, aIndex); 158 Copy(ref boneWeights, aOther.boneWeights, aIndex); 159 //Copy(ref bindposes, aOther.bindposes, aIndex); 160 return i; 161 } 162 public void AssignTo(Mesh aTarget) 163 { 164 aTarget.SetVertices(verts); 165 if (uv1 != null) aTarget.SetUVs(0, uv1); 166 if (uv2 != null) aTarget.SetUVs(1, uv2); 167 if (uv3 != null) aTarget.SetUVs(2, uv3); 168 if (uv4 != null) aTarget.SetUVs(3, uv4); 169 if (normals != null) aTarget.SetNormals(normals); 170 if (tangents != null) aTarget.SetTangents(tangents); 171 if (colors != null) aTarget.SetColors(colors); 172 if (boneWeights != null) aTarget.boneWeights = boneWeights.ToArray(); 173 if (bindposes != null) aTarget.bindposes = bindposes.ToArray(); 174 } 175 } 176 177 public static Mesh GetSubmesh(this Mesh aMesh, int aSubMeshIndex) 178 { 179 if (aSubMeshIndex < 0 || aSubMeshIndex >= aMesh.subMeshCount) 180 return null; 181 int[] indices = aMesh.GetTriangles(aSubMeshIndex); 182 Vertices source = new Vertices(aMesh); 183 Vertices dest = new Vertices(); 184 Dictionary<int, int> map = new Dictionary<int, int>(); 185 int[] newIndices = new int[indices.Length]; 186 for (int i = 0; i < indices.Length; i++) 187 { 188 int o = indices[i]; 189 int n; 190 if (!map.TryGetValue(o, out n)) 191 { 192 n = dest.Add(source, o); 193 map.Add(o, n); 194 } 195 newIndices[i] = n; 196 } 197 dest.bindposes = source.bindposes; 198 Mesh m = new Mesh(); 199 m.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; 200 dest.AssignTo(m); 201 m.triangles = newIndices; 202 return m; 203 } 204 }
转载请注明出处:https://www.cnblogs.com/jietian331/p/17197314.html