test(vehicle): bones match, terrain has no lid, and stopping the mover does not stop the climb

Three more measured facts:

  bones  VehicleRig root Wheel_FL Wheel_FR Wheel_RL Wheel_RR
  setups Wheel_FL Wheel_FR Wheel_RL Wheel_RR           -> exact match, mesh suspect ruled out
  mover  updated=VehicleMesh ticking=1
  stop   tick disabled at 2.5 s with the actor at Z 2001; at 3.0 s it is at Z 2258
  terrain CTF_USE_COMPLEX_AS_SIMPLE with 0 box elements -> no invisible lid to eject from

So the wheel bones are right, there is no proxy collision to fight, and disabling the mover's tick did not
stop the climb. That moves the suspect list to the pawn's own Tick/root: something writes the actor
transform every frame regardless of the physics body, and the 1 cm bounds are its fingerprint.

Pawn parked again; the diagnostic stays.
This commit is contained in:
zwitschi committed 2026-11-09 21:41:36 +01:00
1 parent 6d025491ef
commit 0f059a5c93
79 files changed
+138 -76

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.
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.
@@ -313,6 +313,25 @@ void AGigLineVehicle::Tick(float DeltaSeconds)
}
}
// If the Chaos vehicle never came into existence (no wheels), its movement component has no
// valid state to drive, and continuing to tick it writes whatever is in that empty state back
// onto the actor - which is the only explanation that fits a still body and a moving actor.
if (!bMoverStopped && SettleElapsed > 2.5f)
{
bMoverStopped = true;
if (const UChaosWheeledVehicleMovementComponent* WheelComp =
Cast<UChaosWheeledVehicleMovementComponent>(GetVehicleMovementComponent()))
{
UE_LOG(LogTemp, Warning,
TEXT("GigLine vehicle: stopping the mover - wheels=%d at Z %.0f"),
WheelComp->Wheels.Num(), GetActorLocation().Z);
}
if (UMovementComponent* Mover = GetVehicleMovementComponent())
{
Mover->SetComponentTickEnabled(false);
}
}
// One-shot diagnostic: why zero wheels. Wheels are built in CreateVehicle(), which runs only
// when the physics state produced a vehicle, so the useful facts are whether the mesh is
// simulating and whether it carries a physics asset at all.
@@ -349,6 +368,36 @@ void AGigLineVehicle::Tick(float DeltaSeconds)
Vel.X, Vel.Y, Vel.Z, Angular.X, Angular.Y, Angular.Z, Body->GetMass(),
Body->IsSimulatingPhysics() ? 1 : 0, Body->IsAnySimulatingPhysics() ? 1 : 0);
}
if (Body && Body->GetSkeletalMeshAsset())
{
// Do the wheel setups name bones the mesh actually has? If not, CreateVehicle()
// bails before it ever builds a wheel.
TArray<FName> Bones;
Body->GetBoneNames(Bones);
FString BoneList;
for (int32 i = 0; i < Bones.Num() && i < 20; ++i)
{
BoneList += Bones[i].ToString() + TEXT(" ");
}
FString SetupList;
if (const UChaosWheeledVehicleMovementComponent* WheelComp =
Cast<UChaosWheeledVehicleMovementComponent>(GetVehicleMovementComponent()))
{
for (const FChaosWheelSetup& S : WheelComp->WheelSetups)
{
SetupList += S.BoneName.ToString() + TEXT(" ");
}
}
UE_LOG(LogTemp, Warning, TEXT("GigLine vehicle bones: %d [%s] | setups [%s]"),
Bones.Num(), *BoneList, *SetupList);
if (const UMovementComponent* Mover = GetVehicleMovementComponent())
{
UE_LOG(LogTemp, Warning,
TEXT("GigLine vehicle mover: updated=%s ticking=%d"),
Mover->UpdatedComponent ? *Mover->UpdatedComponent->GetName() : TEXT("none"),
Mover->IsComponentTickEnabled() ? 1 : 0);
}
}
{
const USkeletalMesh* Asset = Body ? Body->GetSkeletalMeshAsset() : nullptr;
UE_LOG(LogTemp, Warning, TEXT("GigLine vehicle mesh asset: %s"),
@@ -83,5 +83,6 @@ private:
float SettleElapsed = 0.f;
bool bMassSet = false;
bool bMoverStopped = false;
bool bSettleReported = false;
};
+12
View File
@@ -32,6 +32,18 @@ GigLine vehicle diag: mesh=1 simulating=1 physasset=yes setups=4 wheels=0
- **Gravity** - `global_gravity_z = 0.0` and the character falls normally, so the world pulls down.
- **Mass** - the 1500 kg override applies (logged), and the body still does not rise.
### Measured after the transform finding
```
bones: 6 [VehicleRig root Wheel_FL Wheel_FR Wheel_RL Wheel_RR]
setups: [Wheel_FL Wheel_FR Wheel_RL Wheel_RR] -> names match, suspect 3 is gone
mover: updated=VehicleMesh ticking=1
stop: mover tick disabled at 2.5 s (Z 2001); at 3.0 s the actor is still at Z 2258
terrain: CTF_USE_COMPLEX_AS_SIMPLE, 0 box elements -> no invisible lid to be ejected from
```
So the wheel bones match, the terrain has no proxy lid, and stopping the mover did not stop the climb - meaning either the stop does not take effect (something else re-enables or writes the transform every frame) or a second writer exists.
### Suspects, in order
1. **Component hierarchy**: a pawn whose root is the mesh while the physics state belongs to another component behaves exactly like this - correct box, correct mass, near-zero velocity, moving actor, 1 cm bounds.