Quick Asset Audit Pro

There is a texture in your project from an event that ended two years ago. No scene references it, no prefab references it, and nobody remembers. Multiply that by a few hundred files and you have a repository nobody wants to clean, because being wrong once means a missing sprite in a build, on a device, with no error to point at.

Every "find unused assets" tool answers the easy half of that question. This one is built around the dangerous half.

FOUR ANSWERS, NOT ONE

• ORPHAN - nothing references it and no string in your code could name it

• BY NAME - a string could reach it, so it cannot be called dead

• NOT SHIPPED - referenced, but no scene in your build settings reaches it

• IN BUILD - referenced, and a build carries it

And a separate flag, SHIPS ANYWAY, for the worst case there is: an asset nothing uses that sits under Resources or StreamingAssets, so every player build you make carries it regardless. "Does anything use it" and "does it ship" are different questions, and a tool that answers only one of them buries that case entirely.

THE LINE NO DEPENDENCY GRAPH CAN SEE

var icon = Resources.Load<Texture2D>("LeafIcon");

LeafIcon is referenced by nothing. A dependency graph says it is dead, and deleting it breaks the game at runtime with no compile error to warn you. This tool reads your scripts for the strings a graph cannot see and reports the icon as undecidable instead.

That covers Resources.Load, Resources.LoadAll, Resources.LoadAsync, AssetDatabase.LoadAssetAtPath and Addressables keys. When a call builds its key at runtime rather than writing it out, the report says how many such call sites exist and treats everything under Resources as undecidable, because no scan can resolve a string that does not exist yet.

Comments and string bodies are blanked out before that check runs. One sentence in a comment that merely mentions Resources.Load would otherwise make your whole Resources folder undecidable, and a report that says "I cannot tell" about everything is worth nothing.

EVERY ROW CARRIES ITS EVIDENCE

A verdict you cannot check is a guess. Open any row and the exact assets that reference it are listed, each one a click away in the Project window. Filter by verdict, by kind, by size or by text, and export the whole report as CSV including the rows the window truncates.

THE SAME PICTURE, SAVED TWICE

Two exports of the same artwork rarely share a single byte - a different compression level is enough to change every one of them. Hashing files finds only the easy half. Every image is decoded and its pixels are hashed, so the same picture is found however it was saved. The sample ships a pair that proves it: two files with no bytes in common and identical pixels.

Decoding reads the file directly, so the importer's Read/Write flag is never touched and no import setting changes.

SPEED, MEASURED

On a generated project of 1270 assets - 1000 textures, 250 prefabs, 10 scenes, 6 of them in the build settings - the whole scan took 0.19 seconds. It runs in 16 ms slices from the editor's update loop rather than one blocking pass, so the window keeps drawing, the progress bar moves and Cancel works at any moment. No modal dialog, no frozen editor.

NOTHING IS CHANGED

The scan reads. It does not move, rename, reimport or delete anything, and it never changes an import setting. Acting on the report is your decision and your keystroke.

REQUIREMENTS

• Unity 2022.3 LTS or newer

• No external dependencies, no accounts, no plugins

• Any render pipeline; the tool never renders anything

HONEST LIMITS

A string this tool cannot see is a string it cannot follow. Keys assembled at runtime, keys read from a data file, and asset names fetched from a server are invisible to any static scan - the report says how many such call sites exist rather than pretending they are not there. Verdicts describe the project as it is on disk right now, so an asset referenced only by a scene you have not committed is an orphan until that scene exists. Editor extensions that load assets by name through their own helpers are not recognised unless the call matches one of the known patterns. Duplicate detection covers PNG, JPG and JPEG; other formats are listed as not compared rather than quietly treated as unique.