feat(hero): facade rework — inscription, medallions, motto band, banner lettering #39

Merged
zwitschi merged 93 commits from hero-facade-0.3.0 into main 2026-11-10 15:37:40 +01:00
37 changed files with 92 additions and 56 deletions
Showing only changes of commit 021aa56121 - Show all commits

No files matched your search

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+46 -10
View File
@@ -305,8 +305,16 @@ def build():
log(f"could not create {MAP}") log(f"could not create {MAP}")
return return
removed = clear(("Demo_", "PlayerStart", "Hero_Facade", "Frontage_", "RetailTrim_", # Repeat until nothing is left: destroying actors while iterating a snapshot can miss
"ShotSequencer")) # some, which is how two Demo_Vehicle_Sedan actors survived into a saved map and the
# scene audit failed on a duplicate label.
removed = 0
for _ in range(4):
pass_removed = clear(("Demo_", "PlayerStart", "Hero_Facade", "Frontage_",
"RetailTrim_", "ShotSequencer"))
removed += pass_removed
if pass_removed == 0:
break
log(f"cleared {removed} previous demo actors") log(f"cleared {removed} previous demo actors")
# --- lighting: fixed daytime ------------------------------------------ # --- lighting: fixed daytime ------------------------------------------
@@ -647,20 +655,48 @@ def build():
unreal.Rotator(pitch=0.0, yaw=90.0, roll=0.0)) unreal.Rotator(pitch=0.0, yaw=90.0, roll=0.0))
log("staged: Demo_PlayerStart on the cut north sidewalk, facing south (+Y)") log("staged: Demo_PlayerStart on the cut north sidewalk, facing south (+Y)")
# The drivable sedan, parked on the carriageway east of the spawn so a review camera # --- vehicle ---------------------------------------------------------
# can frame both. Collision and mass come from PA_Vehicle_Sedan; AGigLineVehicle # The physics pawn and the visible panels are staged as two things on purpose: the
# configures the Chaos wheels from the modelled dimensions. # probe showed the meshes render as plain StaticMeshActors while the same meshes
# attached to the vehicle pawn stay invisible, so the visuals do not depend on the
# pawn until that is solved. A visible car that does not drive yet beats an invisible
# one that does.
vehicle_origin = unreal.Vector(-12950.0, -900.0, 470.0)
vehicle_class = unreal.load_class(None, "/Script/GigLine.GigLineVehicle") vehicle_class = unreal.load_class(None, "/Script/GigLine.GigLineVehicle")
if vehicle_class: if vehicle_class:
# Spawn ON the road: a downward trace measured the surface at Z 366 cm there, so vehicle = spawn(vehicle_class, vehicle_origin, "Demo_Vehicle_Sedan")
# the previous Z 120 spawn buried the car 2.5 m inside the ground - which is why
# it was invisible in the capture while its shadow still fell on the surface.
vehicle = spawn(vehicle_class, unreal.Vector(-12950.0, -900.0, 470.0),
"Demo_Vehicle_Sedan")
log(f"staged: Demo_Vehicle_Sedan ({'ok' if vehicle else 'FAILED'})") log(f"staged: Demo_Vehicle_Sedan ({'ok' if vehicle else 'FAILED'})")
else: else:
log("staged: Demo_Vehicle_Sedan skipped - class not found") log("staged: Demo_Vehicle_Sedan skipped - class not found")
panels = (
("SM_Vehicle_Body", unreal.Vector(0.0, 0.0, -72.0)),
("SM_Vehicle_Glass", unreal.Vector(0.0, 0.0, -72.0)),
("SM_Vehicle_Light_Front", unreal.Vector(0.0, 0.0, -72.0)),
("SM_Vehicle_Light_Rear", unreal.Vector(0.0, 0.0, -72.0)),
("SM_Vehicle_Mirrors", unreal.Vector(0.0, 0.0, -72.0)),
("SM_Vehicle_Wheel", unreal.Vector(139.0, 81.0, -88.0)),
("SM_Vehicle_Wheel", unreal.Vector(139.0, -81.0, -88.0)),
("SM_Vehicle_Wheel", unreal.Vector(-139.0, 81.0, -88.0)),
("SM_Vehicle_Wheel", unreal.Vector(-139.0, -81.0, -88.0)),
)
staged_panels = 0
for index, (mesh_name, offset) in enumerate(panels):
mesh = unreal.EditorAssetLibrary.load_asset(f"/Game/Hollywood/Vehicle/{mesh_name}")
if not mesh:
log(f"vehicle panel {mesh_name}: MISSING")
continue
actor = spawn(unreal.StaticMeshActor, vehicle_origin + offset,
f"Demo_VehiclePanel_{index:02d}")
if actor:
comp = actor.get_component_by_class(unreal.StaticMeshComponent)
if comp:
comp.set_static_mesh(mesh)
comp.set_mobility(unreal.ComponentMobility.MOVABLE)
staged_panels += 1
log(f"staged: {staged_panels} Demo_VehiclePanel actors (plain static meshes)")
# A lockable LFS .umap checks out read-only, which makes save_map silently # A lockable LFS .umap checks out read-only, which makes save_map silently
# return False — chmod u+w first or the staged actors never persist. # return False — chmod u+w first or the staged actors never persist.
umap = os.path.join(unreal.Paths.project_dir(), MAP.replace("/Game/", "Content/") + ".umap") umap = os.path.join(unreal.Paths.project_dir(), MAP.replace("/Game/", "Content/") + ".umap")