test(placement): the character is grounded to within 2 cm, measured three ways

Ran the 158 cm attempt again, with a staging log this time, and it fails the same way: with the
slab at a 158 cm top the player falls to Z -4412 and never hits anything, while the identical
actor collides at 380. Setting the start above the slab put the player on Road_Hollywood at 366 -
so the game's ground here really is road 366 / sidewalk bbox 380, and the Blender-measured 1.58 m
does not describe the shipped map; the blend predates the terrain. The 158 hypothesis was wrong and
is retracted in TODO.md.

Geometry is now measured end to end:

  top surface under player: Z=380 mesh=Cube (actor Z 470)
  body: mesh bottom 382, capsule bottom 382, body above capsule 0 cm

The body's lowest vertex and the capsule bottom agree within 0 cm, sitting 2 cm above the collision
surface. If the captures still read as floating, the cause is the visible sidewalk mesh sitting
lower than its bounding box at that XY - and that value is not reachable from Python, so it needs
a measurement in the mesh itself.
This commit is contained in:
zwitschi committed 2026-11-09 18:02:08 +01:00
1 parent 76859b64cf
commit 579ae2ba41
22 files changed
+33 -21

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.
@@ -411,6 +411,15 @@ void AGigLineCharacter::LogFootProbes()
}
const FVector Feet = GetActorLocation() - FVector(0.f, 0.f, CapsuleHalf);
// Where is the body's lowest point relative to the capsule's? A mesh whose feet sit above
// the capsule bottom looks like a floating character even when the capsule is grounded.
if (const USkeletalMeshComponent* Body = GetMesh())
{
const FBoxSphereBounds B = Body->Bounds;
UE_LOG(LogTemp, Warning,
TEXT("GigLine body: mesh bottom %.0f, capsule bottom %.0f, body above capsule %.0f cm"),
(B.Origin - B.BoxExtent).Z, Feet.Z, (B.Origin - B.BoxExtent).Z - Feet.Z);
}
for (int32 Index = 0; Index < 3; ++Index)
{
FHitResult Hit;
+4 -1
View File
@@ -699,7 +699,10 @@ def build():
sidewalk_collision.set_actor_scale3d(unreal.Vector(279.0, 8.6, 0.08))
comp.set_collision_profile_name("BlockAll")
sidewalk_collision.set_actor_hidden_in_game(True)
log("staged: Demo_SidewalkCollision (invisible, top at Z 380)")
loc = sidewalk_collision.get_actor_location()
scale = sidewalk_collision.get_actor_scale3d()
log(f"staged: Demo_SidewalkCollision at Z {loc.z:.0f}, scale Z {scale.z:.3f} "
f"(top {loc.z + 50.0 * scale.z:.0f} cm)")
spawn(unreal.PlayerStart, unreal.Vector(-13336.0, -1150.0, player_z), "Demo_PlayerStart",
unreal.Rotator(pitch=0.0, yaw=90.0, roll=0.0))