fix(physics): push-out when spawned inside objects (stuck prevention)

When collision is detected at t=0 (already overlapping at step start),
push the sphere out along the collision normal by half-radius instead
of trying to slide with zero displacement (which gets stuck).

Returns Adjusted instead of Slid so the transition loop retries
from the pushed-out position.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-14 12:34:29 +02:00
parent 8e1230c53b
commit f2548146b5

View file

@ -752,11 +752,23 @@ public sealed class Transition
if (bestT >= float.MaxValue)
return TransitionState.OK; // no collision
// Already overlapping at the START of the step (bestT == 0 or very small).
// This happens when the player spawns inside an object or a previous
// step left them penetrating. Push out along the collision normal
// instead of sliding — sliding with zero displacement gets stuck.
if (bestT <= PhysicsGlobals.EPSILON)
{
Vector3 pushOut = bestNormal * (sphereRadius * 0.5f + 0.01f);
sp.AddOffsetToCheckPos(pushOut);
ci.SetCollisionNormal(bestNormal);
ci.SetSlidingNormal(bestNormal);
return TransitionState.Adjusted;
}
// Rewind the sphere to the contact point (before penetration).
if (bestT < 1f)
{
Vector3 contactPos = currPos + movement * bestT;
// Push slightly back along normal to prevent sitting exactly on the surface.
contactPos += bestNormal * 0.005f;
sp.SetCheckPos(contactPos, sp.CheckCellId);
}