"Character stacking: seat at the visual mesh head-top, not the physics capsule height"
▸ SYMPTOM
You build a character-stacking feature (one character riding on another's shoulders/head). The characters are trace controllers, not rigidbodies. You seat the rider at the carrier's body height — and the owner reports "two characters in each other": the rider visibly sinks into the carrier's head and the pair reads as one merged blob instead of a clean stack.
▸ CAUSE
Two things combine:
-
A collider-less trace mover cannot be stood on physically. These characters are trace controllers with no collider (ground checks deliberately exclude the player tag), so nothing physical stops a second character at the first one's head. The "standable head" has to be synthesised: each fixed step (after the mover runs) you pin the rider's feet to the carrier's head-top, zero the rider's fall, and force
Ground. -
The physics capsule height is not the visual head-top. The blocky visual mesh head-top sits higher than the collision capsule. In one verified case the capsule (
BodyHeight) was 0.6 m but the mesh head-top was 0.72 m. Seating at the capsule height put riders 0.12 m too low — straight into the carrier's rendered head.
▸ FIX
Seat at the visual mesh head-top, defined as an explicit constant, not at the capsule height:
// carrier: expose the visual head-top, kept ABOVE the capsule height
const float HeadStandHeight = 0.72f; // visual mesh head-top, not BodyHeight (0.6f)
// rider: each FixedUpdate, AFTER the mover
void PinToCarrier()
{
var seat = carrier.WorldPosition + Vector3.Up * carrier.HeadStandHeight;
WorldPosition = seat; // synthesised feet-pin
Velocity = Velocity.WithZ(0);
IsOnGround = true;
}Keep HeadStandHeight greater than the capsule height on purpose: that keeps the horizontal depenetration pass skipping the stacked pair (they never register as interpenetrating capsules). Add routine asserts for vertical separation between carrier and rider, plus a no-interpenetration scan, so a regression that reintroduces the sink is caught in test rather than by eye.
▸ WHY IT WORKS
Because standing is synthesised rather than physical, you choose the seat height — and the only height that looks right is the one the player actually sees, the visual mesh head-top. The capsule is a collision approximation that sits below the rendered silhouette, so seating against it always looks like the rider has sunk in. Pinning to the visual head-top each step (after the mover, so nothing else moves the rider that frame) and keeping that height above the capsule both fixes the visual and keeps the depenetration pass from fighting the intentional overlap.
- Published