Back
PROJECT CLEANUP UTILITY
Explored 0%
Overview panel full scan 4264 assets 868MB Duplicate detection 440 files 14MB wasted Assets list sorted by size large textures Quarantine tab after batch operation CSV export full asset list with GUID Accessibility font size +4px
Unity 6 Editor · Solo · University

Project Cleanup Utility

A Unity 6 Editor tool that scans a project for unused and duplicate assets, rates how safe each one is to delete, and quarantines, restores or exports them — built on the Editor API and UI Toolkit.

Type
University Module
Module
GDEV50047
Level
5 · Year 2
Engine
Unity 6 (Editor)
Period
Mar – May 2026
Team
Solo
UI
UI Toolkit (USS/UXML)
C# Files
8
Extensions
60+
Unity 6 C# Editor API UI Toolkit USS / UXML AssetDatabase EditorWindow ScriptableObject SHA-256 Hashing Perforce P4V CSV Export Excel Export WCAG 2.1 Okabe-Ito Palette EditorPrefs GUID Traversal
Final Grade 0%
0
Unused Detected
0
Duplicates Found
0
Scan Time
0
Asset Categories
Overview

What is Project Cleanup Utility?

Project Cleanup Utility is a Level 5 solo module project (GDEV50047) at Staffordshire University — a fully featured Unity 6 Editor tool for scanning, categorising, quarantining, and managing unused and duplicate assets in Unity projects. It was built entirely using the Unity Editor API and UI Toolkit, with no external dependencies or native plugins.

The tool was chosen over two other pitched alternatives (an FFmpeg video encoder and a ScriptableObject database editor) because it solves a well-documented, industry-wide pain point: Unity imports and indexes every file in the Assets folder regardless of use, silently accumulating dead weight across editor performance, version control storage, CI/CD pipelines, and developer cognitive load. No first-party Unity tool exists for this.

Project Cleanup Utility main window // Project Cleanup Utility — main application window

Development followed an iterative and incremental approach — scanning first, then quarantine, then dependency graph, then exports, then accessibility — each increment building on a working, tested foundation.

Architecture

Clean Layered Design

The tool is structured across four layers — each with a single, clear responsibility. The UI layer never touches file I/O. The core layer never renders anything. Data models are plain serialisable objects with no Unity coupling. This separation made incremental development straightforward: each increment added a new layer without touching the others.

Core/

Logic

AssetScanner.cs (696 lines) — GUID traversal, reverse-dependency map, string-reference heuristics, content-hash deduplication, Perforce status.

QuarantineManager.cs — move/restore/delete with manifest JSON.

DependencyGraphBuilder.cs — forward/reverse/synthetic reference queries.

Data/

Models

AssetInfo.cs — full asset model: GUID, path, name, category, size, refs/deps lists, Safety rating, IsReadOnly, VCS status.

ScanResult.cs — aggregated scan output with computed stats.

WhitelistConfig.cs — ScriptableObject persisting path/folder/extension/regex exclusion rules.

UI/

Presentation

ProjectCleanupWindow.cs — EditorWindow host with three tabs: Overview, Assets, Quarantine.

ProjectCleanupUtility.uss — UI Toolkit stylesheet driving all colours, typography, and accessibility overrides.

All colour signals defined in USS — never inline C# — so colour-blind overrides work.

Utilities/

Helpers

AssetCategoryResolver.cs — maps 60+ file extensions to 19 AssetCategory enum values. Returns display names and rich tooltip descriptions per extension. Centralised so scanner and UI always agree.

// AssetInfo data model — all state in one place
public string Path, Name, GUID, Extension;
public AssetCategory Category;
public long SizeBytes;
public List<string> DependsOn, ReferencedBy;
public DeletionSafety Safety;      // Safe / Caution / Unsafe / Unknown
public bool IsWhitelisted, IsQuarantined, IsReadOnly;
public VcsStatus PerforceStatus;   // UpToDate / CheckedOutLocal / LockedByOther …
Source files
  • AssetScanner.cs Core/
  • QuarantineManager.cs Core/
  • DependencyGraphBuilder.cs Core/
  • AssetInfo.cs Data/
  • ScanResult.cs Data/
  • WhitelistConfig.cs Data/
  • ProjectCleanupWindow.cs UI/
  • ProjectCleanupUtility.uss UI/
  • AssetCategoryResolver.cs Utilities/
Core Feature

Asset Scanner

AssetScanner.cs (696 lines) is the engine of the tool. It walks every asset in the project via AssetDatabase.GetAllAssetPaths, builds a reverse-dependency map using AssetDatabase.GetDependencies, then classifies each asset's deletion safety. A progress callback fires for every asset so the UI stays live during long scans.

The scanner accounts for string-based asset references — Resources.Load paths, Addressables keys, and serialised string fields in C# — using pre-compiled regex patterns, so assets only referenced by name rather than serialised GUID are not incorrectly flagged as unused.

Asset scanner in progress // Asset scanner — scanning in progress

Deletion safety is computed from the reverse-dependency graph:

● Safe — zero incoming references ● Caution — only ProjectSettings/BuildSettings reference it ● Unsafe — referenced by other project assets

Content-hash duplicate detection groups assets by SHA-256 file content hash. Any group with two or more members is surfaced in the Overview panel with total wasted size. In a live TankController project scan: 219 hash groups, 440 duplicate files, 14.13 MB wasted.

Overview Stats (TankController scan)
ValueMetric
4264total assets
1275unused
1.4 GBtotal size
868.6 MBunused
60.6%waste
3.2sscan time
440duplicate files
14.13 MBin duplicate waste
Features

Full Feature Set

Scan 90%

Safe Quarantine

Files
Moves assets to _Quarantine/, preserving relative directory structure. Manifest JSON tracks original paths. Restore brings assets back to exact original locations. Delete Permanently removes quarantined assets.

Perforce VCS Integration

VCS
Detects active Perforce provider via Provider.isActive. Checks out, marks for delete, and handles LockedByOther state before any file operation. VCS status surfaces in the asset list (UpToDate, CheckedOutLocal, LockedByOther, Added, Deleted, OutOfDate).

Whitelist System

Config
WhitelistConfig ScriptableObject stores exclusion rules: exact paths, folder prefixes, file extensions, and regex patterns. Persists across sessions via version control. Default exclusions for Packages/, Plugins/, StreamingAssets/, Resources/, and .cs/.asmdef/.dll.

CSV & Excel Export

Export
Three-sheet export: Scan Report (summary stats), Asset List (Name, Category, Size, Refs, Deps, Safety, Path, GUID), and Dependency Map (asset, related asset, relationship type). Excel output is formatted and cell-styled. Respects the "Unused Only" filter toggle.
Scan 70%

Multi-Column Asset List

UI
Unity UI Toolkit MultiColumnListView. Sortable by Name, Type, Size, Refs, Deps, Safety, R/O, Path. Category dropdown filter. "Unused Only" toggle. Search box. Rich tooltip on each row showing file extension description. All recycled rows update safety colours via USS class swaps — never inline style.
Scan 30%

Scan History & Comparison

Overview
Caches the previous scan result. Overview panel shows "Changes since last scan" — delta in asset count, unused count, and total size. Timestamp of last scan displayed alongside the comparison block.

Undo Support

Safety
All quarantine and restore operations register with Unity's Undo system. Ctrl+Z rolls back the last batch operation. AssetDatabase.StartAssetEditing / StopAssetEditing used to batch file moves for performance and atomicity.

Select All / Whitelist Selected

Batch
Toolbar actions for batch workflows: Select All surfaces all visible assets for action. Whitelist Selected adds all currently selected assets to WhitelistConfig in one click. Deselect All clears selection without losing scan state.
Accessibility

WCAG 2.1-Informed Layer

The final development iteration was dedicated entirely to accessibility — a deliberate choice to ensure the tool shipped usable, not just functional. The implementation is informed by WCAG 2.1 Perceivable, Operable, and Understandable principles, and the Microsoft Inclusive Design methodology.

Accessibility UI scale 1.5x // Accessibility Settings — UI Scale 1.5x

Colour-Blind Modes

Perceivable
Three modes using the Okabe-Ito palette — the most rigorously validated colour-blind safe palette in academic literature. Deuteranopia, Protanopia, Tritanopia. All colour swaps are USS-only, so the Safety column labels and category bars correctly update. A prior bug — inline label.style.color in C# blocking USS specificity — was fixed by moving all semantic colour to USS classes.

High Contrast Mode

Perceivable
A single USS class on the root element drives a full high-contrast theme — increased border widths, sharper background distinctions, elevated text brightness. Activates globally, affecting every panel and list row simultaneously.

Font Size Adjust

Perceivable
Live slider from –4px to +8px relative to base. Implemented via ApplyFontSize() which folds the delta into root font-size — not transform.scale, which causes layout clipping in UI Toolkit. Persists across sessions via EditorPrefs.

Keyboard Navigation

Operable
Full Tab/Enter/Arrow navigation. F5 re-scan. Ctrl+A select all. Delete key quarantines selection. Ctrl+1/2/3 tab switching. A shortcut help dialog surfaces all keybindings — bridging novice (visible buttons) and expert (keyboard-driven) usage modes, as per Norman (2013).
Key Engineering LessonAny element whose colour is a semantic signal — not merely decorative — must have its colour defined in USS from the start, so accessibility overrides can win. Inline label.style.color set in C# sits at the highest specificity and permanently blocks USS rules, regardless of selector complexity.
Challenges

What Went Wrong

  1. Bug 01

    transform.scale breaking layout

    The first UI Scale implementation set rootVisualElement.transform.scale to a Vector3 scalar. UI Toolkit's layout pass runs before the render transform, so at any scale other than 1.0, the visual content and layout bounds diverge — content clips off the bottom of the window. Fixed by abandoning transform.scale entirely and folding the scale factor into the base font size via ApplyFontSize().

  2. Bug 02

    Safety label colours not updating in colour-blind mode

    The Safety column bindCell callback was setting label.style.color directly in C# — three separate hardcoded RGBA values. Inline styles override all USS rules regardless of specificity. Fixed by removing all inline colour from C# and using USS safety classes (safety-safe, safety-caution, safety-unsafe) managed by the bindCell callback.

  3. Bug 03

    :focus-within row highlight failing

    A focused-row USS rule using :focus-within caused silent console warnings in Unity's UI Toolkit. USS does not support the :focus-within pseudo-class in the Unity runtime. The row highlight was dropped; the per-control :focus indicator was retained as a functional compromise.

ReflectionThe tool shipped covering scanning, categorisation, quarantine, restore, deletion, CSV/Excel export, full tab UI, comprehensive settings, and a complete accessibility layer. The one acknowledged gap: screen reader support via Unity's Accessibility hierarchy API — which is primarily designed for runtime UI and is not straightforwardly applicable to EditorWindow tooling. A future production version would also add automated contrast ratio validation at build time.
Milestones

Trophies Earned

Perfect ScoreAwarded 100% — First Class for GDEV50047 Tools Development — a perfect score
Nothing Left UnseenFull unused asset detection via GUID-based AssetDatabase.GetDependencies — no build required
Spot the TwinContent-hash duplicate detection across 219 groups, 440 files — 14.13 MB flagged in a live TankController project scan
Safe KeepingSafe quarantine workflow — moves assets to _Quarantine/ with manifest JSON, preserving original paths for full restore
Traffic LightsDeletion safety ratings: Safe / Caution / Unsafe — based on reverse dependency analysis
Spreadsheet WizardExport to CSV and formatted Excel — scan report, full asset list, and dependency map sheets
Inclusive by DesignFull accessibility layer: Colour-Blind Mode (Okabe-Ito palette), High Contrast, Font Size slider, UI Scale, keyboard navigation
Checked OutPerforce (P4V) VCS integration — checks out, locks, and stages assets before quarantine/delete operations