Last active
January 18, 2018 03:44
-
-
Save onotchi/a9780012e9d6a7cd489bde15a2be7a25 to your computer and use it in GitHub Desktop.
SubMesh単位でMeshを作り直す
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Linq; | |
using UnityEditor; | |
using UnityEngine; | |
public class SubMeshExporter : ScriptableObject | |
{ | |
// Use this for initialization | |
private void Start() | |
{ | |
} | |
// Update is called once per frame | |
private void Update() | |
{ | |
} | |
[MenuItem("Custom/Export/ExportSubMesh(from SkinnedMeshRenderer)")] | |
private static void ExportSubMeshFromSkinnedMeshRenderer() | |
{ | |
//何も選択されていなかったら終了 | |
if (Selection.gameObjects.Length == 0) return; | |
var gameObject = Selection.gameObjects[0]; | |
var skinnedMeshRenderer = gameObject.GetComponentInChildren<SkinnedMeshRenderer>(); | |
//選択したオブジェクトにSkinnedMeshRendererが無かったら終了 | |
if (skinnedMeshRenderer == null) return; | |
//出力 | |
SubMeshExporter.ExportSubMesh(gameObject.name, skinnedMeshRenderer.sharedMesh); | |
} | |
[MenuItem("Custom/Export/ExportSubMesh(from MeshFilter)")] | |
private static void ExportSubMeshFromMeshFilter() | |
{ | |
//何も選択されていなかったら終了 | |
if (Selection.gameObjects.Length == 0) return; | |
var gameObject = Selection.gameObjects[0]; | |
var meshFilter = gameObject.GetComponentInChildren<MeshFilter>(); | |
//選択したオブジェクトにMeshFilterが無かったら終了 | |
if (meshFilter == null) return; | |
//出力 | |
SubMeshExporter.ExportSubMesh(gameObject.name, meshFilter.sharedMesh); | |
} | |
private static void ExportSubMesh(string name, Mesh mesh) | |
{ | |
//フォルダ名の決定 | |
var guid = AssetDatabase.CreateFolder("Assets", name + "SubMeshes"); | |
var folderName = AssetDatabase.GUIDToAssetPath(guid); | |
//サブメッシュの出力 | |
var title = "Export"; | |
var info = "Exporting subMesh {0}/{1} ..."; | |
try | |
{ | |
for (int index = 0; index < mesh.subMeshCount; index++) | |
{ | |
EditorUtility.DisplayProgressBar(title, string.Format(info, index + 1, mesh.subMeshCount), (float)(index + 1) / (float)mesh.subMeshCount); | |
SubMeshExporter.CreateMesh(folderName, mesh, index); | |
} | |
} | |
finally | |
{ | |
EditorUtility.ClearProgressBar(); | |
} | |
} | |
private static void CreateMesh(string folderName, Mesh parent, int index) | |
{ | |
//サブメッシュの三角形リスト取得 | |
var triangles = parent.GetTriangles(index); | |
//サブメッシュの三角形リスト(同値省く)取得 | |
var trianglesUnique = triangles.Distinct().ToList(); | |
//サブメッシュの頂点位置とテクスチャ座標の切り出し | |
var vertices = trianglesUnique.Select(x => parent.vertices[x]).ToArray(); | |
var uv = trianglesUnique.Select(x => parent.uv[x]).ToArray(); | |
var normals = trianglesUnique.Select(x => parent.normals[x]).ToArray(); | |
var tangents = trianglesUnique.Select(x => parent.tangents[x]).ToArray(); | |
//三角形リストの値をサブメッシュに合わせてシフト | |
var triangleNewIndexes = trianglesUnique.Select((x, i) => new { OldIndex = x, NewIndex = i }).ToDictionary(x => x.OldIndex, x => x.NewIndex); | |
var triangleConv = triangles.Select(x => triangleNewIndexes[x]).ToArray(); | |
//メッシュ作成 | |
var mesh = new Mesh(); | |
mesh.vertices = vertices; | |
mesh.uv = uv; | |
mesh.normals = normals; | |
mesh.tangents = tangents; | |
mesh.triangles = triangleConv; | |
//バウンディングボリュームと法線の再計算 | |
mesh.RecalculateBounds(); | |
mesh.RecalculateNormals(); | |
//出力 | |
AssetDatabase.CreateAsset(mesh, folderName + "/submesh" + index + ".asset"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment