Skip to content

Instantly share code, notes, and snippets.

@onotchi
Last active January 18, 2018 03:44
Show Gist options
  • Save onotchi/a9780012e9d6a7cd489bde15a2be7a25 to your computer and use it in GitHub Desktop.
Save onotchi/a9780012e9d6a7cd489bde15a2be7a25 to your computer and use it in GitHub Desktop.
SubMesh単位でMeshを作り直す
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