Skip to content

analyze: scene/preload dependencies broken outside BuildPipeline.BuildAssetBundles (dangling assets rows; object -1 rows) #81

Description

@SkowronskiAndrew

Summary

analyze mishandles scene/preload dependencies for every build type except BuildPipeline.BuildAssetBundles. Two related symptoms share one root cause: the synthetic "Scene" object (and therefore a valid SceneId) is only created when a SerializedFile is named BuildPlayer-<SceneName>. For any other naming, AssetBundleHandler still writes scene rows and PreloadDataHandler still writes preload rows, but they reference a Scene object that was never inserted.

Background

A scene has no single Unity object. To represent it in the database, SerializedFileSQLiteWriter synthesizes one "Scene" object (type -1, object id = (SerializedFileIdProvider.GetId(sceneName), 0)) and uses it as the target of:

  • the assets row written by AssetBundleHandler for the scene container entry,
  • the scene-content dependencies (scene -> each object in the scene's SerializedFiles),
  • the PreloadData dependencies written by PreloadDataHandler.

The Scene object is only created when m_RegexSceneFile (BuildPlayer-([^\.]+)) matches the file name. That naming is produced only by BuildPipeline.BuildAssetBundles.

Bug 1: Addressables / Scriptable Build Pipeline scenes are unrepresented

SBP/Addressables name scene files CAB-<hash of scene path> (and .sharedAssets), so m_RegexSceneFile never matches. No Scene object is created, but AssetBundleHandler (running for the scene bundle's AssetBundle object) still computes a scene object id from the .unity container name and inserts an assets row pointing at it. Result: dangling assets rows and missing scene-content dependencies.

The Multi-Process Build Pipeline (CAB-<scene GUID>) is affected the same way.

Bug 2: Player builds attribute PreloadData dependencies to object -1

Player builds contain a PreloadData object (in globalgamemanagers) but no scenes named BuildPlayer-*, so SceneId stays -1. PreloadDataHandler unconditionally uses ctx.SceneId as the object, so its rows are written to asset_dependencies with object = -1. These are meaningless rows.

Evidence

Measured with analyze on reference builds:

Build Scene objs (type=-1) assets orphan assets (no objects row) asset_dependencies with object=-1
Player 0 0 0 29
BuildPipeline.BuildAssetBundles 0* 7 0 0
ContentDirectory 0 0 0 0
Addressables (SBP) 0 19158 261 (all .unity) 50252

* The BuildPipeline test data happens to contain no scenes, so its scene path is not exercised — likely why this went unnoticed.

All 261 orphan assets in the Addressables DB are .unity scene entries whose assets.object has no matching objects row.

Suggested direction (not prescriptive)

Detect scene SerializedFiles independent of the BuildPlayer- naming (e.g. via the AssetBundle object's m_IsStreamedSceneAssetBundle / scene container entries, or by matching the scene name from the container rather than the file name), and make PreloadDataHandler a no-op (or attribute correctly) when there is no scene. The two symptoms are best fixed together since they stem from the same Scene-object/SceneId resolution.

Pointers

  • Analyzer/SQLite/Writers/SerializedFileSQLiteWriter.csm_RegexSceneFile, scene object synthesis, scene-content dependency loop.
  • Analyzer/SQLite/Handlers/AssetBundleHandler.csm_SceneNameRegex, assets row for scenes.
  • Analyzer/SQLite/Handlers/PreloadDataHandler.cs — uses ctx.SceneId unconditionally.

(These locations now carry comments describing the limitation.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions