Skip to content

Latest commit

 

History

History
178 lines (132 loc) · 13.5 KB

File metadata and controls

178 lines (132 loc) · 13.5 KB

Unity Asset Workbench

License: CC BY-NC-ND 4.0 CI and Release

Desktop explorer for Unity game data. Browse a game folder, index serialized assets and UnityFS bundles, filter by name/type/path, inspect format-aware previews, then extract raw or decoded assets without modifying game files.

Current state: Phase 2 implemented. Browse/index/resume, on-demand inspection, raw extraction, common media decoding, and streaming catalog export build on .NET 10 and Windows.

Features

  • Native PhotinoEx folder dialogs
  • MudBlazor desktop UI with light/dark themes
  • Recursive discovery of Unity serialized files and asset bundles
  • Bounded parallel container scanning with Auto/2/4/8/16 worker control
  • Low-allocation streaming metadata reads instead of full object-tree materialization
  • Live server-paged SQLite results while assets are still being parsed
  • Live elapsed-time and estimated-remaining timers in scan progress
  • Compact SQLite catalog with per-container stop-and-resume support
  • Automatic cache invalidation when the detected game build changes
  • GameObject/component hierarchy derived from Unity object references
  • Master/detail object browser with components shown only in the GameObject inspector
  • Asset name, type, path ID, byte size, Unity version, source file, and bundle-entry index
  • Search plus asset-type filter
  • Single and multi-select raw extraction
  • Cancellable scans and bulk exports
  • Copyable asset locations
  • Bounded hex inspector for every asset and decoded TextAsset previews
  • On-demand Texture2D and Sprite previews with PNG export
  • AudioClip metadata, browser playback for supported containers, and encoded-audio export
  • Streaming CSV/JSON export directly from SQLite without loading the catalog into memory
  • Scan warnings isolated per source file
  • Remembered data and export folders
  • Read-only source handling

Stack

PhotinoEx currently describes itself as pre-production software. Bootstrap applies focused Windows fixes: response streams positioned at EOF, app navigation racing WebView2's initial about:blank, and native window-procedure delegate lifetime. Desktop integration stays isolated in UnityAssetWorkbench.Desktop so host replacement or upstream migration does not affect Unity parsing code. See DESIGN.md.

Prerequisites

  • .NET SDK 10.0.302 or compatible newer patch
  • Git
  • Windows: Microsoft Edge WebView2 Evergreen Runtime
  • Linux/macOS: runtime dependencies required by PhotinoEx; current MVP is verified only on Windows

Setup

Fetch pinned PhotinoEx source:

./scripts/bootstrap-photinoex.ps1

Restore, build, and test:

dotnet restore UnityAssetWorkbench.slnx
dotnet build UnityAssetWorkbench.slnx
dotnet test tests/UnityAssetWorkbench.Tests/UnityAssetWorkbench.Tests.csproj

Run:

dotnet run --project src/UnityAssetWorkbench.Desktop/UnityAssetWorkbench.Desktop.csproj

For WebView diagnostics, set UAW_WEBVIEW_DEBUG_PORT to an unused local port before launch. Debugging stays disabled by default.

CI and releases

GitHub Actions builds, tests, and audits NuGet packages on every pull request and push to main. Push a semantic version tag reachable from main to publish a self-contained Windows x64 ZIP, SHA-256 checksum, generated release notes, and retained workflow artifact:

git checkout main
git pull --ff-only
git tag -a v0.1.0 -m "Unity Asset Workbench v0.1.0"
git push origin v0.1.0

Accepted tags use vMAJOR.MINOR.PATCH with an optional SemVer prerelease suffix, such as v0.2.0-beta.1. Tags not reachable from main fail before publishing. Re-running a successful tag workflow replaces existing release assets instead of creating a duplicate release.

Usage

  1. Select a Unity GameName_Data folder or game root.
  2. Leave Scan workers on Auto, or choose a fixed worker count.
  3. Choose Scan assets.
  4. Watch results populate immediately; filters remain available during the scan.
  5. Choose the eye icon to inspect an object. GameObject components appear as children in the inspector; supported assets render text, image, audio, or metadata previews on demand.
  6. Use Export decoded in the inspector for a format-aware artifact, or the row action for exact .raw bytes.
  7. Tick one or more browser rows and choose Extract selected for bulk raw extraction.
  8. Use Catalog export to stream every indexed row to CSV or JSON.

Auto uses logical processor count - 1, capped at eight workers, reserving one processor for UI and system work. Manual choices are also capped below the machine's logical processor count. Fixed long-lived workers each own one parser; the embedded class package and selected Unity database are reused across containers, while container files and streams are unloaded after every job. Higher values can help on fast SSDs with many small containers, but compressed bundles can consume substantial memory; reduce the count if the system starts paging.

Catalog metadata is read directly from each serialized object stream. Per-type read plans and iterators are reused. Indexing eagerly reads GameObject.m_Name and component m_GameObject pointers only; names for other asset types are loaded from the source when that asset is inspected. The scanner avoids copying each complete object into a temporary buffer, constructing full AssetsTools.NET value trees, or allocating a UI record for every database row.

Parsed addresses are committed to SQLite in 16,384-record transactions through one scan-lifetime writer connection. WAL-friendly normal synchronization, a larger checkpoint interval, prepared inserts, bounded memory/cache settings, partial indexes, and suppressed redundant type/index writes reduce write amplification. The MudBlazor table requests only its current page, filter, and search results from the database; it never receives a complete game catalog. During scanning, the active page refreshes at most once every three seconds and uses the scan count as a temporary paging hint instead of recounting millions of rows. The separate 250 ms progress refresh updates counts, elapsed time, and the remaining-time estimate without querying or copying the catalog.

SQLite normalizes source containers, bundle entries, and type names instead of repeating full paths and computed UI strings for every object. Each asset row stores only its entry ID, path ID, type ID, eager GameObject name when applicable, byte size, and optional GameObject owner pointer. Raw asset bytes are never cached. Completed-container markers and warnings are loaded with one manifest query when resuming, rather than opening SQLite once per candidate file. If a scan stops, committed partial batches remain viewable; only containers marked complete are resumed, while an incomplete container is cleared and reparsed.

The browser keeps only one page of records plus explicit selections in memory. Opening a GameObject queries its components on demand. Extraction reopens the selected Unity source and reads the raw object payload only when requested.

The catalog stores each decodable component's local m_GameObject reference. Components with a matching GameObject in the same serialized container are removed from the main object browser and indexed beneath their owner. Inspecting a GameObject opens a responsive side panel with its component type, path ID, serialized size, location, copy, and extraction actions. The hierarchy index and filtered object list are rebuilt only when scan data or filters change, rather than on every render.

Each scan worker loads the embedded compressed Unity class package and selects the database matching the serialized file's reported Unity version. This allows stripped player files to decode the actual GameObject.m_Name and component ownership fields instead of displaying GameObject #PathId. The bundled package is 289,605 bytes with SHA-256 129e1f80f930415db6779fe6089afa75280cb51462bcee812beab6cd81a764c6.

Build identity combines the game executable product/file version when available with candidate container paths, sizes, and modification times. Cache data lives under %LOCALAPPDATA%/UnityAssetWorkbench/catalog-cache; source game folders remain untouched. Each normalized game root owns one catalog.db. A detected build or schema change replaces that database and forces a complete reparse, preventing old builds from accumulating indefinitely.

Raw extracted files contain the exact serialized object payload stored by Unity, named from m_Name when type metadata permits it, otherwise from asset type and path ID. Output uses .raw to avoid implying decoded media. Existing output names receive numeric suffixes. Extraction never overwrites existing output or source data.

Format-aware inspection reopens only the selected object. TextAssets decode as UTF-8/UTF-16 or fall back to hex. Texture2D and direct-texture Sprite records decode to PNG. AudioClip inspection resolves embedded and streamed resource payloads, identifies WAV/Ogg/FLAC/MP3/FSB data, and exposes browser playback only when the container is browser-supported and small enough. Audio export preserves the detected encoded container; it does not transcode codecs.

Preview work has strict limits: 64 KiB generic hex, 512 KiB text, 8 MiB browser audio, 24 MiB encoded image data, 16.7 million preview pixels, 67 million export pixels, and 256 MiB decoded artifacts. Larger supported assets still expose metadata and decoded export where safe. Catalog CSV/JSON output streams one SQLite row at a time and includes components, ownership IDs, source/entry addresses, sizes, versions, and names.

Project layout

src/
  UnityAssetWorkbench.Core/            Domain records and service contracts
  UnityAssetWorkbench.Infrastructure/  Unity scanning, extraction, settings
  UnityAssetWorkbench.Desktop/         PhotinoEx host and MudBlazor UI
tests/
  UnityAssetWorkbench.Tests/           Discovery, naming, and catalog tests
external/
  PhotinoEx.version                     Pinned upstream revision
scripts/
  bootstrap-photinoex.ps1               Dependency bootstrap

Known limitations

  • Asset names use embedded Unity type trees or the bundled version-matched class database. Unsupported/custom engine versions still show Type #PathId.
  • GameObject/component nesting uses the same metadata fallback; undecodable or external owner references remain top-level objects.
  • MonoBehaviour field decoding needs managed assemblies or IL2CPP metadata and is not implemented.
  • Addressables catalog resolution is not implemented.
  • PhotinoEx upstream currently produces WindowsBase reference warnings during Windows builds.
  • Very large assets above 2 GB are rejected by single-object extraction.
  • Parallelism is per container; entries within one bundle are parsed sequentially.
  • A content mutation that preserves path, byte length, and modification timestamp cannot be distinguished by the fast build fingerprint.
  • No cache-management UI yet.
  • Audio export preserves known WAV/Ogg/FLAC/MP3/FSB payloads; codec transcoding and FSB decoding are not implemented.
  • Sprite PNG uses direct texture-rectangle cropping; uncommon rotated atlas packing is not transformed yet.
  • Texture and audio decoding depend on Unity format/version support in AssetsTools.NET and its texture decoder.

Roadmap

  • Mesh to OBJ/glTF
  • MonoBehaviour structured tree viewer
  • Resource-stream resolution (.resS, .resource)
  • Addressables catalog browser
  • Asset dependency graph and reference search
  • Safe replacement workflow with backups and explicit write mode
  • SQLite full-text name/path search for very large catalogs
  • Cache inspection, size limits, and clear-cache controls
  • Cross-platform packaging and signed releases

License

Original Unity Asset Workbench source code, documentation, and project-owned assets are licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. You may share unmodified copies with attribution for noncommercial purposes. Modified versions may not be distributed under this license.

See NOTICE for attribution and scope. Third-party dependencies, vendored PhotinoEx source, embedded Unity class data, trademarks, and game assets retain their respective licenses and rights.

Safety and legal

Workbench defaults to read-only scanning and never patches game data. Back up games before using future write features. Extract only assets you have rights to use; game licenses and copyright law may restrict redistribution or modification.