This file provides guidance to AI agents when working with code in this repository.
UnityDataTools is a .NET 9.0 command-line tool for analyzing Unity build output (AssetBundles, Player builds, Addressables). It extracts data from Unity's proprietary binary formats into SQLite databases and human-readable text files. The tool showcases the UnityFileSystemApi native library and serves as both a production tool and reference implementation.
# Build entire solution in Release mode
dotnet build -c Release
# Build from solution file
dotnet build UnityDataTools.sln -c Release
# Build specific project
dotnet build UnityDataTool/UnityDataTool.csproj -c ReleaseOutput location (Windows): UnityDataTool\bin\Release\net9.0\UnityDataTool.exe
# Intel Mac
dotnet publish UnityDataTool -c Release -r osx-x64 -p:PublishSingleFile=true -p:UseAppHost=true
# Apple Silicon Mac
dotnet publish UnityDataTool -c Release -r osx-arm64 -p:PublishSingleFile=true -p:UseAppHost=true# Run all tests
dotnet test
# Run tests for specific project
dotnet test UnityFileSystem.Tests/UnityFileSystem.Tests.csproj
dotnet test Analyzer.Tests/Analyzer.Tests.csproj
dotnet test UnityDataTool.Tests/UnityDataTool.Tests.csproj
# Run tests with filter
dotnet test --filter "FullyQualifiedName~SerializedFile"Test projects: UnityFileSystem.Tests, Analyzer.Tests, UnityDataTool.Tests, TestCommon (helper library)
# Show all commands
UnityDataTool --help
# Analyze AssetBundles into SQLite database
UnityDataTool analyze /path/to/bundles -o database.db
# Dump binary file to text format
UnityDataTool dump /path/to/file.bundle -o /output/path
# Extract archive contents
UnityDataTool archive extract file.bundle -o contents/
# Find reference chains to an object
UnityDataTool find-refs database.db -n "ObjectName" -t "Texture2D"UnityDataTool (CLI executable)
├── Analyzer → SQLite database generation
├── TextDumper → Human-readable text output
├── ReferenceFinder → Object reference chain tracing
└── UnityFileSystem → C# wrapper for native library
└── UnityFileSystemApi (native .dll/.dylib/.so)
Native Interop: UnityFileSystem wraps UnityFileSystemApi (native library from Unity Editor) via P/Invoke in DllWrapper.cs. The native library reads Unity Archive and SerializedFile formats.
TypeTree Navigation: Unity binary files contain TypeTrees that describe object serialization. The RandomAccessReader class navigates these trees like property accessors: reader["m_Name"].GetValue<string>(). This enables the tool to interpret objects without hardcoded type knowledge.
Parser Pattern: ISQLiteFileParser interface allows multiple parsers to handle different file formats:
SerializedFileParser- Unity binary files (AssetBundles, Player data)AddressablesBuildLayoutParser- JSON build reports
Handler Registry: Type-specific handlers extract specialized properties for Unity object types. Handlers implement ISQLiteHandler and are registered in SerializedFileSQLiteWriter.m_Handlers:
MeshHandler- vertices, indices, bones, blend shapesTexture2DHandler- width, height, format, mipmapsShaderHandler- variants, keywords, subprogramsAudioClipHandler- compression, channels, frequencyAnimationClipHandler- legacy flag, eventsAssetBundleHandler- dependencies, preload dataPreloadDataHandler- preloaded assets
SQL Schema Resources: Each handler has an embedded .sql resource file defining its tables and views (e.g., Analyzer/SQLite/Resources/Mesh.sql). Views join type-specific tables with the base objects table.
Command Pattern: SQL operations are encapsulated in classes derived from AbstractCommand with CreateCommand(), SetValue(), ExecuteNonQuery() methods.
Program.cs→HandleAnalyze()→AnalyzerTool.Analyze()- AnalyzerTool finds files matching search pattern
- For each file, parsers are tried in order (JSON first, then SerializedFile)
SerializedFileParser.ProcessFile():- Checks for Unity Archive signature → calls
MountArchive() - Otherwise treats as SerializedFile → calls
OpenSerializedFile()
- Checks for Unity Archive signature → calls
SerializedFileSQLiteWriter.WriteSerializedFile():- Iterates through
sf.Objects - Gets TypeTree via
sf.GetTypeTreeRoot(objectId) - Creates
RandomAccessReaderto navigate properties - Looks up type-specific handler in
m_Handlersdictionary - Handler extracts specialized properties (e.g., MeshHandler reads vertex count)
- Writes to
objectstable + type-specific table (e.g.,meshes) - Optionally processes PPtrs (references) and calculates CRC32
- Iterates through
- SQLiteWriter finalizes database with indexes and views
Entry Points:
UnityDataTool/Program.cs- CLI using System.CommandLineUnityDataTool/Commands/- Command handlers (Analyze.cs, Dump.cs, Archive.cs, FindReferences.cs)
Core Libraries:
UnityFileSystem/UnityFileSystem.cs- Init(), MountArchive(), OpenSerializedFile()UnityFileSystem/DllWrapper.cs- P/Invoke bindings to native libraryUnityFileSystem/SerializedFile.cs- Represents binary data filesUnityFileSystem/RandomAccessReader.cs- TypeTree property navigation
Analyzer:
Analyzer/AnalyzerTool.cs- Main API entry pointAnalyzer/SQLite/SQLiteWriter.cs- Base class for database writersAnalyzer/SQLite/Writers/SerializedFileSQLiteWriter.cs- Handler registrationAnalyzer/SQLite/Writers/AddressablesBuildLayoutSQLWriter.cs- JSON report processingAnalyzer/SQLite/Handlers/- Type-specific extractorsAnalyzer/SerializedObjects/- RandomAccessReader-based property readersAnalyzer/SQLite/Resources/- SQL DDL schema files
TextDumper:
TextDumper/TextDumperTool.cs- Converts binary to YAML-like text
ReferenceFinder:
ReferenceFinder/ReferenceFinderTool.cs- Traces object dependency chains
-
Create handler class implementing
ISQLiteHandler:Analyzer/SQLite/Handlers/FooHandler.cs -
Create reader class using RandomAccessReader:
Analyzer/SerializedObjects/Foo.cs -
Register handler in
SerializedFileSQLiteWriter.cs:m_Handlers["Foo"] = new FooHandler();
-
Create SQL schema resource:
Analyzer/SQLite/Resources/Foo.sqlDefine tables (e.g.,
foos) and views (e.g.,foo_viewjoiningobjectsandfoos) -
Reference the schema in handler's GetResourceName() method
- Create parser implementing
ISQLiteFileParser - Create writer derived from
SQLiteWriter - Add parser to
AnalyzerTool.parserslist - Create SQL schema and Command classes as needed
Example: Addressables support uses AddressablesBuildLayoutParser + AddressablesBuildLayoutSQLWriter to parse JSON build reports.
TypeTrees describe how Unity objects are serialized (property names, types, offsets). They enable:
- Backward compatibility - reading files from different Unity versions
- Generic parsing without hardcoded type definitions
- Support for custom MonoBehaviours/ScriptableObjects
Critical: Player builds exclude TypeTrees by default for performance. To analyze Player data, enable the "ForceAlwaysWriteTypeTrees" diagnostic switch during build.
- Unity Archive - Container format (AssetBundles, .data files). Can be mounted as virtual filesystem.
- SerializedFile - Binary format storing Unity objects with TypeTree metadata.
- Addressables BuildLayout - JSON build report (buildlogreport.json, AddressablesReport.json)
The SQLite output uses views extensively to join base objects table with type-specific tables:
object_view- All objects with basic propertiesmesh_view- Objects + mesh-specific columnstexture_view- Objects + texture-specific columnsshader_view- Objects + shader-specific columnsview_breakdown_by_type- Aggregated size by typeview_potential_duplicates- Assets included multiple timesasset_view- Explicitly assigned assets onlyshader_keyword_ratios- Keyword variant analysis
See Analyzer/README.md and Documentation/addressables-build-reports.md for complete database schema documentation.
TypeTree Errors: "Invalid object id" during analyze means SerializedFile lacks TypeTrees. Enable ForceAlwaysWriteTypeTrees or use files built with TypeTrees.
File Loading Warnings: "Failed to load... File may be corrupted" is normal for non-Unity files in analyzed directories. Use -p search pattern to filter (e.g., -p "*.bundle").
SQL UNIQUE Constraint Errors: Occurs when same SerializedFile name appears in multiple archives. This happens when analyzing multiple builds in same directory or using AssetBundle variants. See Documentation/comparing-builds.md for solutions.
Mac Security: "UnityFileSystemApi.dylib cannot be opened" - Open System Preferences → Security & Privacy and allow the library.
The native library is included for Windows, Mac, and Linux in UnityFileSystem/ directory. It's backward compatible and reads data files from most Unity versions.
To use a specific Unity version's library:
- Find library in Unity Editor installation:
{UnityEditor}/Data/Tools/ - Copy to
UnityDataTool/UnityFileSystem/:- Windows:
UnityFileSystemApi.dll - Mac:
UnityFileSystemApi.dylib - Linux:
UnityFileSystemApi.so
- Windows:
- Rebuild the tool
UnityFileSystemTestData is a Unity project that generates test data for the test suites. TestCommon provides shared test utilities.