Skip to content

Instantly share code, notes, and snippets.

@kasari
Created December 22, 2023 09:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kasari/ce7c09a88f2751e63aa7cbd967b100c7 to your computer and use it in GitHub Desktop.
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
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