qa: make the demo walkable — terrain collision root cause, spawn, scripted QA

The reported fall-through was a misdiagnosis: the player never fell. The
imported Terrain_DEM had only a bounding-box simple collision proxy, so a
downward trace anywhere in the block hit the terrain at Z 819 (the mesh
bbox max) and the street sat under an invisible 8 m lid. Standing on that
box looked plausible, which is why it read as working.

- add UGigLineAssetTools (C++): force CTF_UseComplexAsSimple on a static
  mesh. UE 5.8 dropped bUseComplexAsSimpleCollision and Python cannot set
  the flag; the builder also saves the asset, since the flag lives there
  and a map-only save silently reverts it.
- spawn (-13336, -1150, 600): inside the carved corridor (the cut is a
  10.7 m half-width around the road centreline), lands on the road at 456.
- fix ResetToStart returning to the mid-air PlayerStart captured in
  BeginPlay: StartLocation is now captured on the first grounded frame.
- HighResShot 1280x720 instead of "1280 720", which is a multiplier.
- add -qaselftest: scripted walk/reset/pause on a core ticker plus a
  swept ground transect. Results: walk 746 cm/2 s with Z steady, reset
  0 cm from spawn, pause/unpause 1/0, transect 84 samples 0 holes.
- rebase onto main, keeping the frontage materials and placement fixes.
This commit is contained in:
zwitschi committed 2026-11-08 11:56:19 +01:00
1 parent fee26ade10
commit 52b1212cf3
34 files changed
+591 -92

No files matched your search

+12 -2
View File
@@ -50,6 +50,12 @@ def import_fbx(path, name, collision="complex"):
smd.convert_scene_unit = False
smd.force_front_x_axis = False
smd.normal_import_method = unreal.FBXNormalImportMethod.FBXNIM_IMPORT_NORMALS
# Generate collision at import. A default FBX static-mesh import creates NO
# collision primitives, so CTF_USE_COMPLEX_AS_SIMPLE later has nothing to use
# and the player falls through the walkable surfaces (observed at runtime:
# ground trace under the spawn hits nothing). auto_generate_collision bakes
# collision geometry into the mesh so the walkable plane actually blocks.
smd.auto_generate_collision = True
task.options = ui
unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([task])
@@ -71,8 +77,12 @@ def import_fbx(path, name, collision="complex"):
log(f"{name:18} import ok size=({mx.x - mn.x:.0f}, {mx.y - mn.y:.0f}, {mx.z - mn.z:.0f}) cm "
f"min_z={mn.z:.1f} collision=none")
return
trace = (unreal.CollisionTraceFlag.CTF_USE_COMPLEX_AS_SIMPLE
if collision == "complex" else unreal.CollisionTraceFlag.CTF_USE_SIMPLE_AND_COMPLEX)
# Walkable surfaces block with SIMPLE + COMPLEX collision so the player's
# capsule always has ground: CFG_USE_SIMPLE_AND_COMPLEX uses the auto-
# generated simple collision AND the mesh triangles. (Complex-as-simple
# alone only worked if the mesh carried complex collision, which a default
# FBX static-mesh import does not.)
trace = unreal.CollisionTraceFlag.CTF_USE_SIMPLE_AND_COMPLEX
try:
body = mesh.get_editor_property("body_setup")
body.set_editor_property("collision_trace_flag", trace)