Created
December 22, 2023 09:14
-
-
Save kasari/ce7c09a88f2751e63aa7cbd967b100c7 to your computer and use it in GitHub Desktop.
Unity editor extension to create a list of meshes on a Scene and sort them by number of vertices or triangles
This file contains 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 System.Collections.Generic; | |
using UnityEditor; | |
using UnityEngine; | |
public class MeshInfoWindow : EditorWindow | |
{ | |
private enum TableSortState | |
{ | |
None, | |
VertexCount, | |
TriangleCount, | |
ObjectCount, | |
TotalTriangleCount | |
} | |
private List<MeshInfo> meshInfos = new List<MeshInfo>(); | |
private Vector2 scrollPosition; | |
private TableSortState sortState = TableSortState.None; | |
[MenuItem("Window/Mesh Info")] | |
static void Init() | |
{ | |
var window = GetWindow<MeshInfoWindow>(); | |
window.Show(); | |
} | |
void OnGUI() | |
{ | |
if (GUILayout.Button("Initialize", GUILayout.Height(30))) | |
{ | |
Initialize(); | |
} | |
EditorGUILayout.BeginHorizontal(); | |
GUILayout.FlexibleSpace(); | |
GUILayout.Label("Sort By:"); | |
if (GUILayout.Button("Vertex Count")) | |
{ | |
SortBy(TableSortState.VertexCount); | |
} | |
if (GUILayout.Button("Triangle Count")) | |
{ | |
SortBy(TableSortState.TriangleCount); | |
} | |
if (GUILayout.Button("Object Count")) | |
{ | |
SortBy(TableSortState.ObjectCount); | |
} | |
if (GUILayout.Button("Total Triangle Count")) | |
{ | |
SortBy(TableSortState.TotalTriangleCount); | |
} | |
EditorGUILayout.EndHorizontal(); | |
GUILayout.Space(10); | |
EditorGUILayout.BeginHorizontal(); | |
GUILayout.Label("Mesh Name", GUILayout.Width(200)); | |
GUILayout.Label("Vertex Count", GUILayout.Width(100)); | |
GUILayout.Label("Triangle Count", GUILayout.Width(100)); | |
GUILayout.Label("Object Count", GUILayout.Width(100)); | |
GUILayout.Label("Total Triangle Count", GUILayout.Width(150)); | |
EditorGUILayout.EndHorizontal(); | |
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); | |
foreach (var entry in meshInfos) | |
{ | |
EditorGUILayout.BeginHorizontal(); | |
if (GUILayout.Button(entry.MeshName, GUILayout.Width(200))) | |
{ | |
Selection.objects = entry.MeshObjects.ToArray(); | |
} | |
GUILayout.Label(entry.VertexCount.ToString(), GUILayout.Width(100)); | |
GUILayout.Label(entry.TriangleCount.ToString(), GUILayout.Width(100)); | |
GUILayout.Label(entry.ObjectCount.ToString(), GUILayout.Width(100)); | |
GUILayout.Label(entry.TotalTriangleCount.ToString(), GUILayout.Width(150)); | |
EditorGUILayout.EndHorizontal(); | |
} | |
EditorGUILayout.EndScrollView(); | |
} | |
void Initialize() | |
{ | |
meshInfos.Clear(); | |
sortState = TableSortState.None; | |
// Scene上の全てのメッシュを取得 | |
var meshFilters = FindObjectsOfType<MeshFilter>(); | |
var meshObjectDictionary = new Dictionary<Mesh, List<GameObject>>(); | |
foreach (var meshFilter in meshFilters) | |
{ | |
if (meshFilter.sharedMesh != null) | |
{ | |
if (!meshObjectDictionary.ContainsKey(meshFilter.sharedMesh)) | |
{ | |
meshObjectDictionary.Add(meshFilter.sharedMesh, new List<GameObject>()); | |
} | |
meshObjectDictionary[meshFilter.sharedMesh].Add(meshFilter.gameObject); | |
} | |
} | |
foreach (var entry in meshObjectDictionary) | |
{ | |
int vertexCount = entry.Key.vertices.Length; | |
int triangleCount = entry.Key.triangles.Length / 3; | |
int objectCount = entry.Value.Count; | |
int totalTriangleCount = triangleCount * objectCount; | |
meshInfos.Add(new MeshInfo(entry.Key.name, vertexCount, triangleCount, objectCount, totalTriangleCount, entry.Value)); | |
} | |
SortBy(TableSortState.TotalTriangleCount); | |
} | |
void SortBy(TableSortState newState) | |
{ | |
if (sortState == newState) | |
{ | |
meshInfos.Reverse(); | |
} | |
else | |
{ | |
meshInfos = SortMeshInfos(meshInfos, newState); | |
sortState = newState; | |
} | |
} | |
List<MeshInfo> SortMeshInfos(List<MeshInfo> infos, TableSortState state) | |
{ | |
switch (state) | |
{ | |
case TableSortState.VertexCount: | |
return infos.OrderByDescending(info => info.VertexCount).ToList(); | |
case TableSortState.TriangleCount: | |
return infos.OrderByDescending(info => info.TriangleCount).ToList(); | |
case TableSortState.ObjectCount: | |
return infos.OrderByDescending(info => info.ObjectCount).ToList(); | |
case TableSortState.TotalTriangleCount: | |
return infos.OrderByDescending(info => info.TotalTriangleCount).ToList(); | |
default: | |
return infos; | |
} | |
} | |
private class MeshInfo | |
{ | |
public string MeshName { get; private set; } | |
public int VertexCount { get; private set; } | |
public int TriangleCount { get; private set; } | |
public int ObjectCount { get; private set; } | |
public int TotalTriangleCount { get; private set; } | |
public List<GameObject> MeshObjects { get; private set; } | |
public MeshInfo(string meshName, int vertexCount, int triangleCount, int objectCount, int totalTriangleCount, List<GameObject> meshObjects) | |
{ | |
MeshName = meshName; | |
VertexCount = vertexCount; | |
TriangleCount = triangleCount; | |
ObjectCount = objectCount; | |
TotalTriangleCount = totalTriangleCount; | |
MeshObjects = meshObjects; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment