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:
parent
8e1230c53b
commit
f2548146b5
1 changed files with 13 additions and 1 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue