Skip to content

Commit 9b62102

Browse files
[#131] Support ContentLayout v3 (Unity 6.7) with v2 backward compatibility (#147)
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 9b62102

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)