Skip to content

Instantly share code, notes, and snippets.

@aobond2
Created February 13, 2026 16:10
Show Gist options
  • Select an option

  • Save aobond2/c9cb2f4225a9b23c30bd251916b6581b to your computer and use it in GitHub Desktop.

Select an option

Save aobond2/c9cb2f4225a9b23c30bd251916b6581b to your computer and use it in GitHub Desktop.
Check all object in a scene, get info on triangle count, texture size, and memory size. Then enable sorting based on these.
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace Editor
{
public class AssetAuditorWindow : EditorWindow
{
private Vector2 _scrollPos;
private List<AuditResult> _results = new List<AuditResult>();
// Enum to keep track sorting state
private enum SortBy { Name, Tris, TextureRes, MemorySize }
private SortBy currentSort = SortBy.Tris;
private bool ascending = false;
[MenuItem("Tools/Asset Auditor")]
public static void ShowWindow() => GetWindow<AssetAuditorWindow>("Asset Auditor");
private void OnGUI()
{
GUILayout.Label("Scene Performance Auditor", EditorStyles.boldLabel);
if (GUILayout.Button("Scan Current Scene", GUILayout.Height(30)))
{
PerformAudit();
}
EditorGUILayout.Space();
// Header
EditorGUILayout.BeginHorizontal((EditorStyles.helpBox));
if (GUILayout.Button("Object Name", EditorStyles.toolbarButton, GUILayout.Width(200))) SetSort(SortBy.Name);
if (GUILayout.Button("Tris", EditorStyles.toolbarButton, GUILayout.Width(70))) SetSort(SortBy.Tris);
if (GUILayout.Button("Texture Res", EditorStyles.toolbarButton, GUILayout.Width(100))) SetSort(SortBy.TextureRes);
if (GUILayout.Button("VRAM", EditorStyles.toolbarButton, GUILayout.Width(80))) SetSort(SortBy.MemorySize);
EditorGUILayout.EndHorizontal();
// Result List
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
foreach (var result in _results)
{
EditorGUILayout.BeginHorizontal("box");
GUILayout.Label(result.Name, GUILayout.Width(200));
//Color code high poly counts
GUI.color = result.Tris > 5000 ? Color.red : Color.white;
GUILayout.Label(result.Tris.ToString(), GUILayout.Width(70));
GUI.color = Color.white;
GUILayout.Label(result.TEXRes, GUILayout.Width(100));
// Display memory in MB
string memDisplay = (result.MemSize / (1024f * 1024f)).ToString("F2") + " MB";
GUI.color = result.MemSize > 1000000 ? Color.yellow : Color.white; // If more than 1 MB
GUILayout.Label(memDisplay, GUILayout.Width(80));
GUI.color = Color.white;
if (GUILayout.Button("Select", GUILayout.Width(60)))
{
Selection.activeGameObject = result.Go;
EditorGUIUtility.PingObject(result.Go);
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
void SetSort(SortBy mode)
{
if (currentSort == mode) ascending = !ascending;
else
{
currentSort = mode;
ascending = false;
}
SortResults();
}
void SortResults()
{
switch (currentSort)
{
case SortBy.Name: _results = ascending ? _results.OrderBy(r => r.Name).ToList() : _results.OrderByDescending(r => r.Name).ToList(); break;
case SortBy.Tris: _results = ascending ? _results.OrderBy(r => r.Tris).ToList() : _results.OrderByDescending(r => r.Tris).ToList(); break;
case SortBy.TextureRes: _results = ascending ? _results.OrderBy(r => r.TEXHeight * r.TEXWidth).ToList() : _results.OrderByDescending(r => r.TEXHeight * r.TEXWidth).ToList(); break;
case SortBy.MemorySize: _results = ascending ? _results.OrderBy(r => r.MemSize).ToList() : _results.OrderByDescending(r => r.MemSize).ToList(); break;
}
}
void PerformAudit()
{
_results.Clear();
MeshFilter[] meshFilters = FindObjectsByType<MeshFilter>(FindObjectsSortMode.None);
foreach (var meshFilter in meshFilters)
{
int triCount = meshFilter.sharedMesh ? meshFilter.sharedMesh.triangles.Length / 3 : 0;
string texInfo = "None";
long memory = 0;
int w = 0, h = 0;
Renderer renderer = meshFilter.gameObject.GetComponent<Renderer>();
if (renderer != null && meshFilter.GetComponent<Renderer>()?.sharedMaterial?.mainTexture != null)
{
var tex = meshFilter.GetComponent<Renderer>().sharedMaterial.mainTexture;
w = tex.width;
h = tex.height;
texInfo = $"{w}x{h}";
// Get actual compress size in bytes
memory = UnityEngine.Profiling.Profiler.GetRuntimeMemorySizeLong(tex);
}
_results.Add(new AuditResult
{
Name = meshFilter.name,
Tris = triCount,
TEXRes = texInfo,
TEXWidth = w,
TEXHeight = h,
MemSize = memory,
Go = meshFilter.gameObject,
});
}
// Sort by triangles descending
_results = _results.OrderByDescending(r => r.Tris).ToList();
}
struct AuditResult
{
public string Name;
public int Tris;
public string TEXRes;
public int TEXWidth;
public int TEXHeight;
public long MemSize;
public GameObject Go;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment