test(vehicle): the terrain alone reproduces it, and two collision fixes did not help
Built the map-content bisect the task asked for: Tools/ue_vehicle_probe_map.py duplicates ReviewMap, optionally adds one demo mesh and the pawn, and saves it as VehicleProbe. control (no extra mesh) Z 300 -> 297 rests on the review floor + Terrain_DEM Z 300 -> 498 thrown upward So Terrain_DEM alone reproduces the fault in a map that works. Two fixes were tried: - Tools/ue_clear_simple_collision.py cleared the auto-generated convex hulls from all 76 site/street meshes - the terrain had ONE convex element over 279 m - and set them to complex-as-simple. Still rises. - The terrain component set to QueryOnly, so traces hit it and physics ignores it. Still rises. Neither changed the behaviour, so the ejection is neither the convex hull nor the collision channel. The next probe is the complex triangles themselves: give Terrain_DEM no collision at all in the probe map and see whether the pawn falls. If it falls, the triangle winding is pushing bodies out of the ground mesh - the same inverted-winding family that made the sidewalk unstandable earlier. Both tools have README rows; the pawn is parked again.
This commit is contained in:
1 parent
410d924403
commit
a1771cb55f
103 files changed
+393
-174
No files matched your search
@@ -0,0 +1,105 @@
|
||||
"""Add one piece of demo content to ReviewMap and save it as a vehicle probe level.
|
||||
|
||||
GIGLINE_PROBE_ASSET=Terrain_DEM <engine>/UnrealEditor-Cmd <uproject> \
|
||||
-run=pythonscript -script=<repo>/Tools/ue_vehicle_probe_map.py -nullrhi -unattended -nopause
|
||||
|
||||
Why: the Chaos pawn falls correctly on ReviewMap's empty floor and is thrown upward everywhere in
|
||||
DemoMap. Rather than guess which of DemoMap's 593 staged meshes is responsible, add them one group
|
||||
at a time to the map that works and watch for the moment the pawn stops falling. With no
|
||||
GIGLINE_PROBE_ASSET set, the level is a plain copy of ReviewMap - the control.
|
||||
|
||||
Assets are looked up as /Game/Hollywood/Site/<name> first, then /Game/Hollywood/Buildings/<name>.
|
||||
Result: /tmp/gigline/vehicle-probe.txt
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import unreal
|
||||
|
||||
RESULT = "/tmp/gigline/vehicle-probe.txt"
|
||||
TARGET = "/Game/Test/VehicleProbe"
|
||||
SOURCE = "/Game/Test/ReviewMap"
|
||||
SEARCH = ("/Game/Hollywood/Site", "/Game/Hollywood/Buildings",
|
||||
"/Game/Hollywood/Streets", "/Game/Hollywood/Props")
|
||||
lines = []
|
||||
|
||||
|
||||
def log(message):
|
||||
lines.append(str(message))
|
||||
unreal.log(str(message))
|
||||
|
||||
|
||||
def find_asset(name):
|
||||
for folder in SEARCH:
|
||||
path = f"{folder}/{name}"
|
||||
if unreal.EditorAssetLibrary.does_asset_exist(path):
|
||||
return path
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
wanted = os.environ.get("GIGLINE_PROBE_ASSET", "").strip()
|
||||
if not unreal.EditorAssetLibrary.does_asset_exist(SOURCE):
|
||||
log(f"missing source level {SOURCE}")
|
||||
lines.append("VERDICT: FAIL")
|
||||
return
|
||||
target = TARGET
|
||||
# A level that the previous run left behind cannot always be deleted while the editor holds it,
|
||||
# so fall back to a suffixed name rather than failing the probe.
|
||||
for suffix in ("", "_b", "_c", "_d"):
|
||||
target = TARGET + suffix
|
||||
if not unreal.EditorAssetLibrary.does_asset_exist(target):
|
||||
break
|
||||
unreal.EditorAssetLibrary.delete_asset(target)
|
||||
if not unreal.EditorAssetLibrary.does_asset_exist(target):
|
||||
break
|
||||
if not unreal.EditorAssetLibrary.duplicate_asset(SOURCE, target):
|
||||
log(f"could not duplicate {SOURCE} -> {TARGET}")
|
||||
lines.append("VERDICT: FAIL")
|
||||
return
|
||||
log(f"duplicated {SOURCE} -> {target}")
|
||||
unreal.EditorLevelLibrary.load_level(target)
|
||||
|
||||
if wanted:
|
||||
path = find_asset(wanted)
|
||||
if path is None:
|
||||
log(f"MISSING asset {wanted} in {SEARCH}")
|
||||
lines.append("VERDICT: FAIL")
|
||||
return
|
||||
mesh = unreal.EditorAssetLibrary.load_asset(path)
|
||||
actor = unreal.EditorLevelLibrary.spawn_actor_from_class(
|
||||
unreal.StaticMeshActor, unreal.Vector(0.0, 0.0, 0.0))
|
||||
actor.get_component_by_class(unreal.StaticMeshComponent).set_static_mesh(mesh)
|
||||
actor.set_actor_label(f"Probe_{wanted}")
|
||||
log(f"staged probe mesh {path} at the origin")
|
||||
else:
|
||||
log("control run: no extra content")
|
||||
|
||||
vehicle_class = unreal.load_class(None, "/Script/GigLine.GigLineVehicle")
|
||||
if vehicle_class:
|
||||
pawn = unreal.EditorLevelLibrary.spawn_actor_from_class(
|
||||
vehicle_class, unreal.Vector(600.0, 0.0, 300.0))
|
||||
pawn.set_actor_label("Probe_Vehicle")
|
||||
log("staged the Chaos pawn at (600, 0, 300)")
|
||||
else:
|
||||
log("vehicle class not found")
|
||||
|
||||
if unreal.EditorLevelLibrary.save_current_level():
|
||||
log(f"saved {target}")
|
||||
lines.append(f"LEVEL: {target}")
|
||||
lines.append("VERDICT: PASS")
|
||||
else:
|
||||
log(f"save failed for {target}")
|
||||
lines.append("VERDICT: FAIL")
|
||||
|
||||
|
||||
try:
|
||||
main()
|
||||
except Exception as exc: # noqa: BLE001
|
||||
import traceback
|
||||
log(f"FAILED: {type(exc).__name__}: {exc}")
|
||||
log(traceback.format_exc())
|
||||
lines.append("VERDICT: FAIL")
|
||||
|
||||
with open(RESULT, "w") as f:
|
||||
f.write("\n".join(lines) + "\n")
|
||||
Reference in new issue
Block a user