fix(materials): stop orphaning references; add a scene audit gate

The blockout cleaning pass found the map was rendering with 604 of 620 mesh actors
unmaterialed - every kit piece and all theatre trim.

Cause: ensure_material() deleted and recreated each /Game/Hollywood/Site/M_* asset on
every run, so actors staged by other tools kept references to deleted assets and fell
back to the default material. Nothing errored; the map looked merely slightly flat.

- Materials are now updated IN PLACE (load, delete_all_material_expressions, rebuild
  the graph, recompile, save). Material.expressions is protected from Python, so the
  editing library's deleter is used.
- 53 duplicated kit actor labels fixed (both shop piers of a bay shared one name).
- New Tools/ue_audit_scene.py gates the scene: every mesh actor has a material, every
  verified frontage span is within +/-1 m (via ue_placement), no duplicate labels.
- render_screenshots.sh now runs the chain in the required order (demo map -> kit ->
  theatre -> audit -> cameras -> capture) and exits non-zero on an audit failure,
  because the demo builder rebuilds materials and later staging must follow it.

Scene audit: 0 failures. Packaged QA PASS. Spawn-view reference score 0.72.
This commit is contained in:
zwitschi committed 2026-11-08 22:48:00 +01:00
1 parent 442d0f3d73
commit 600633cd5b
35 files changed
+226 -55

No files matched your search

+15 -6
View File
@@ -118,14 +118,23 @@ def ensure_material(mat_name, spec, textures=None):
does not read as one flat specular value.
"""
path = f"/Game/Hollywood/Site/{mat_name}"
if unreal.EditorAssetLibrary.does_asset_exist(path):
# Rebuilt every run so a look change cannot be masked by a stale asset.
unreal.EditorAssetLibrary.delete_asset(path)
mat = unreal.AssetToolsHelpers.get_asset_tools().create_asset(
mat_name, "/Game/Hollywood/Site", unreal.Material, unreal.MaterialFactoryNew())
lib = unreal.MaterialEditingLibrary
# Update the existing material IN PLACE rather than deleting and recreating it.
# Deleting the asset to force a look rebuild silently orphaned every reference:
# after one demo-builder run, all 598 kit actors and the theatre trim pointed at
# deleted materials and rendered with the default one (604 actors with no
# material), while the map itself looked merely "a bit flat".
mat = unreal.EditorAssetLibrary.load_asset(path)
if mat is None:
mat = unreal.AssetToolsHelpers.get_asset_tools().create_asset(
mat_name, "/Game/Hollywood/Site", unreal.Material, unreal.MaterialFactoryNew())
else:
# Clear the old graph so a removed node cannot survive a look change.
# `Material.expressions` is protected from Python, so use the editing
# library's own deleter rather than reading the array.
lib.delete_all_material_expressions(mat)
def node(cls):
return lib.create_material_expression(mat, cls)