Skip to content

Commit ae03cf2

Browse files
[#131] Support ContentLayout v3 (Unity 6.7) with v2 backward compatibility
The Unity 6.7 ContentLayout.json schema (v3) renames ID to StableId (no .cfid extension), replaces ContentHash with ArtifactIndex, references loadables by index instead of ObjectIdHash, and drops the loadable AssetPath/OutputLFID fields (no more remapping into clusters). UnityDataTools.Models.ContentLayout now tracks v3; the v2 schema is preserved as a reference definition in UnityDataTools.Models.V2. Analyze accepts both versions: v2 files are upgraded in memory to the v3 model (ContentLayoutV2Upgrader), so a single write path and a single database schema serve both. The content_layout tables move to the v3 shape (loadable_index key, stable_id, artifact_index, is_root_asset holding the 1-based root position); the v2-only source data (asset_path, source_lfid) lands in extra columns that exist only in databases imported from a v2 layout. PRAGMA user_version bumped to 8. The previous v2 layout of the LeadingEdge build is archived at TestCommon/Data/ContentLayoutVersions/v2 as a permanent fixture, the LeadingEdge ContentDirectory reference data is regenerated with a 6.7 editor (v3 layout), and UnityFileSystemApi.dll is updated to a local 6.7 build (debug config, Windows only - the mac/linux libraries still need a 6.7 build).
1 parent 3e01a91 commit ae03cf2

70 files changed

Lines changed: 1139 additions & 591 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎Analyzer/Properties/Resources.Designer.cs‎

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Analyzer/Properties/Resources.resx‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,12 @@
247247
<data name="ContentLayoutLoadableObjects" type="System.Resources.ResXFileRef, System.Windows.Forms">
248248
<value>..\Resources\ContentLayoutLoadableObjects.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
249249
</data>
250+
<data name="ContentLayoutLoadableObjectsV2" type="System.Resources.ResXFileRef, System.Windows.Forms">
251+
<value>..\Resources\ContentLayoutLoadableObjectsV2.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
252+
</data>
253+
<data name="ContentLayoutLoadableObjectsView" type="System.Resources.ResXFileRef, System.Windows.Forms">
254+
<value>..\Resources\ContentLayoutLoadableObjectsView.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
255+
</data>
250256
<data name="ContentLayoutLoadableScenes" type="System.Resources.ResXFileRef, System.Windows.Forms">
251257
<value>..\Resources\ContentLayoutLoadableScenes.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
252258
</data>

‎Analyzer/Resources/ContentLayoutLoadableDependencies.sql‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ CREATE TABLE IF NOT EXISTS content_layout_loadable_dependencies
22
(
33
-- The loadable objects each content file references.
44
serialized_file_index INTEGER, -- references content_layout_serialized_files.file_index
5-
object_id_hash TEXT -- references content_layout_loadable_objects.object_id_hash
5+
loadable_index INTEGER -- references content_layout_loadable_objects.loadable_index
66
);

‎Analyzer/Resources/ContentLayoutLoadableObjects.sql‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ CREATE TABLE IF NOT EXISTS content_layout_loadable_objects
22
(
33
-- The objects that can be loaded on demand, identified independently of the content file that
44
-- holds them, plus where each came from in the source project.
5-
object_id_hash TEXT, -- hash of GUID, LFID and identifier_type
5+
loadable_index INTEGER, -- the json array index; how the other content_layout tables name a loadable
66
guid TEXT, -- AssetDatabase GUID of the source asset
7-
asset_path TEXT,
8-
lfid INTEGER, -- local file id of the object in the source asset
7+
lfid INTEGER, -- local file id of the object in its output content file
98
identifier_type INTEGER,
109
serialized_file_index INTEGER, -- content_layout_serialized_files.file_index; NULL if dropped from the build
11-
output_lfid INTEGER, -- local file id of the object in its output content file
12-
is_root_asset INTEGER,
13-
PRIMARY KEY (object_id_hash)
10+
is_root_asset INTEGER, -- 1-based position in the layout's RootAssets; 0 when not a root asset
11+
PRIMARY KEY (loadable_index)
1412
);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
CREATE TABLE IF NOT EXISTS content_layout_loadable_objects
2+
(
3+
-- The objects that can be loaded on demand, identified independently of the content file that
4+
-- holds them, plus where each came from in the source project. This is the variant created when
5+
-- a version 2 layout (Unity 6.6) is imported; it adds source columns that newer layout versions
6+
-- no longer record.
7+
loadable_index INTEGER, -- the json array index; how the other content_layout tables name a loadable
8+
guid TEXT, -- AssetDatabase GUID of the source asset
9+
lfid INTEGER, -- local file id of the object in its output content file
10+
identifier_type INTEGER,
11+
serialized_file_index INTEGER, -- content_layout_serialized_files.file_index; NULL if dropped from the build
12+
is_root_asset INTEGER, -- 1-based position in the layout's RootAssets; 0 when not a root asset
13+
asset_path TEXT, -- v2 layouts only: path of the source asset
14+
source_lfid INTEGER, -- v2 layouts only: local file id of the object in the source asset
15+
PRIMARY KEY (loadable_index)
16+
);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CREATE VIEW IF NOT EXISTS content_layout_loadable_objects_view AS
2+
-- Loadables resolved to their analyzed object. The object columns are NULL in a layout-only
3+
-- database. Selects the loadable table's columns as-is, so the v2-only columns (asset_path,
4+
-- source_lfid) appear when the imported layout was version 2.
5+
SELECT l.*,
6+
f.filename,
7+
o.id AS object, t.name AS type, o.name, o.size
8+
FROM content_layout_loadable_objects l
9+
LEFT JOIN content_layout_serialized_files_view f ON f.file_index = l.serialized_file_index
10+
LEFT JOIN objects o ON o.serialized_file = f.serialized_file AND o.object_id = l.lfid
11+
LEFT JOIN types t ON t.id = o.type;

‎Analyzer/Resources/ContentLayoutSerializedFiles.sql‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ CREATE TABLE IF NOT EXISTS content_layout_serialized_files
33
-- The content files (.cf) the ContentDirectory build produced, one row per entry in the
44
-- layout's SerializedFiles array.
55
file_index INTEGER, -- the json array index; how the other content_layout tables name a file
6-
cfid TEXT, -- symbolic .cfid reference string (for built-ins: the built-in path)
6+
stable_id TEXT, -- identity hash used to reference this file (for built-ins: the built-in path)
77
is_builtin INTEGER,
8-
content_hash TEXT, -- NULL for built-ins; the filename is content_hash || '.cf'
8+
artifact_index INTEGER, -- content_layout_binary_artifacts.artifact_index; NULL for built-ins
99
serialized_file INTEGER, -- serialized_files.id; NULL for built-ins and for a layout-only analyze
1010
PRIMARY KEY (file_index)
1111
);
Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,31 @@
11
CREATE VIEW IF NOT EXISTS content_layout_serialized_files_view AS
2-
-- One row per layout content file with its derived filename, artifact size and core-table link.
3-
-- Built-in entries have no file on disk, so their path (cfid) is shown as the filename.
4-
SELECT f.file_index, f.cfid, f.is_builtin,
5-
CASE WHEN f.is_builtin = 1 THEN f.cfid ELSE f.content_hash || '.cf' END AS filename,
2+
-- One row per layout content file with its content hash, derived filename, artifact size and
3+
-- core-table link. Built-in entries have no file on disk, so their path (stable_id) is shown as
4+
-- the filename.
5+
SELECT f.file_index, f.stable_id, f.is_builtin, f.artifact_index,
6+
CASE WHEN f.is_builtin = 1 THEN f.stable_id ELSE ba.content_hash || '.cf' END AS filename,
7+
ba.content_hash,
68
ba.size,
79
f.serialized_file,
810
sf.archive
911
FROM content_layout_serialized_files f
10-
LEFT JOIN content_layout_binary_artifacts ba ON ba.content_hash = f.content_hash AND ba.category = 'contentfile'
12+
LEFT JOIN content_layout_binary_artifacts ba ON ba.artifact_index = f.artifact_index
1113
LEFT JOIN serialized_files sf ON sf.id = f.serialized_file;
1214

1315
CREATE VIEW IF NOT EXISTS content_layout_source_assets_view AS
1416
-- Source asset to the content file(s) it was built into.
15-
SELECT s.asset_path, f.file_index, f.content_hash || '.cf' AS filename, f.serialized_file
17+
SELECT s.asset_path, f.file_index, f.filename, f.serialized_file
1618
FROM content_layout_source_assets s
17-
INNER JOIN content_layout_serialized_files f ON f.file_index = s.serialized_file_index;
19+
INNER JOIN content_layout_serialized_files_view f ON f.file_index = s.serialized_file_index;
1820

1921
CREATE VIEW IF NOT EXISTS content_layout_serialized_file_dependencies_view AS
2022
-- File-to-file dependency edges with filenames resolved on both sides.
2123
SELECT d.serialized_file_index, src.filename, d.position,
22-
d.dependency_index, dep.filename AS dependency_filename, dep.cfid AS dependency_cfid
24+
d.dependency_index, dep.filename AS dependency_filename, dep.stable_id AS dependency_stable_id
2325
FROM content_layout_serialized_file_dependencies d
2426
INNER JOIN content_layout_serialized_files_view src ON src.file_index = d.serialized_file_index
2527
INNER JOIN content_layout_serialized_files_view dep ON dep.file_index = d.dependency_index;
2628

27-
CREATE VIEW IF NOT EXISTS content_layout_loadable_objects_view AS
28-
-- Loadables resolved to their analyzed object. The object columns are NULL in a layout-only database.
29-
SELECT l.object_id_hash, l.guid, l.asset_path, l.lfid, l.is_root_asset,
30-
f.content_hash || '.cf' AS filename,
31-
o.id AS object, t.name AS type, o.name, o.size
32-
FROM content_layout_loadable_objects l
33-
LEFT JOIN content_layout_serialized_files f ON f.file_index = l.serialized_file_index
34-
LEFT JOIN objects o ON o.serialized_file = f.serialized_file AND o.object_id = l.output_lfid
35-
LEFT JOIN types t ON t.id = o.type;
36-
3729
CREATE VIEW IF NOT EXISTS content_layout_binary_artifacts_view AS
3830
-- Artifacts with their on-disk filename derived from the content hash and category.
3931
SELECT artifact_index, content_hash, category, size,
@@ -48,11 +40,10 @@ FROM content_layout_binary_artifacts;
4840

4941
CREATE VIEW IF NOT EXISTS content_layout_resource_files_view AS
5042
-- The data files (.resS/.resource) each content file uses, derived from the artifact graph.
51-
SELECT f.file_index, f.content_hash || '.cf' AS filename,
43+
SELECT f.file_index, f.filename,
5244
ra.category, rav.filename AS data_filename, ra.size
53-
FROM content_layout_serialized_files f
54-
INNER JOIN content_layout_binary_artifacts ca ON ca.content_hash = f.content_hash AND ca.category = 'contentfile'
55-
INNER JOIN content_layout_artifact_references r ON r.artifact_index = ca.artifact_index
45+
FROM content_layout_serialized_files_view f
46+
INNER JOIN content_layout_artifact_references r ON r.artifact_index = f.artifact_index
5647
INNER JOIN content_layout_binary_artifacts ra ON ra.artifact_index = r.referenced_artifact_index
5748
INNER JOIN content_layout_binary_artifacts_view rav ON rav.artifact_index = ra.artifact_index
5849
WHERE ra.category IN ('texture', 'mesh', 'audio', 'video');

‎Analyzer/Resources/Init.sql‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ WHERE m.type = 'Material';
168168

169169
INSERT INTO types (id, name) VALUES (-1, 'Scene');
170170

171-
PRAGMA user_version = 8;
171+
PRAGMA user_version = 9;
172172

173173
PRAGMA synchronous = OFF;
174174
PRAGMA journal_mode = MEMORY;

‎Analyzer/SQLite/Commands/ContentLayout/AddContentLayoutLoadableDependency.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ internal class AddContentLayoutLoadableDependency : AbstractCommand
1212
protected override Dictionary<string, SqliteType> Fields => new()
1313
{
1414
{ "serialized_file_index", SqliteType.Integer },
15-
{ "object_id_hash", SqliteType.Text }
15+
{ "loadable_index", SqliteType.Integer }
1616
};
1717
}
1818
}

0 commit comments

Comments
 (0)