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

 

posted @ 2023-03-09 10:04  孤独の巡礼  阅读(279)  评论(0编辑  收藏  举报