Smooth wall-climb lean-out offset to remove stepping
Replace the dead-beat-with-deadzone perpendicular controller with an exponential follow that targets one skin-width beyond the offset, so the capsule never penetrates the wall and the controller's depenetration no longer fights back. Removes the quantizing deadzone that caused stepping. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
27301f34d9
commit
534477f6f7
1 file changed
+10
-7
@@ -92,6 +92,9 @@ public class PlayerCharacterController : MonoBehaviour
|
||||
[Tooltip("How fast the lean-out offset eases back to the wall while moving (units/second).")]
|
||||
public float wallOffsetReturnSpeed = 2f;
|
||||
|
||||
[Tooltip("How snappily the body follows the lean-out offset (1/second). Higher = tighter, lower = smoother.")]
|
||||
public float wallOffsetFollow = 12f;
|
||||
|
||||
[Tooltip("Grace period (seconds) of lost contact tolerated before leaving wall-climb mode.")]
|
||||
public float wallExitGrace = 0.15f;
|
||||
|
||||
@@ -406,14 +409,14 @@ public class PlayerCharacterController : MonoBehaviour
|
||||
velocity += alongWall.normalized * climbSpeed;
|
||||
if (found)
|
||||
{
|
||||
// Hold the chosen standoff (offset, 0 = flush) without fighting the controller's
|
||||
// depenetration. A deadzone wider than the skin-width settling distance ignores
|
||||
// sub-threshold gap noise that otherwise buzzed the body back and forth along the
|
||||
// wall normal. Clamp guards against probe spikes.
|
||||
// Smoothly approach the chosen standoff. Target one skin-width beyond the offset so
|
||||
// the capsule rests just outside the surface (offset 0 = flush): the controller's
|
||||
// depenetration never fights back, so there's no buzz and no quantizing deadzone is
|
||||
// needed. Exponential follow keeps it framerate-stable; clamp guards probe spikes.
|
||||
const float maxPerpSpeed = 8f;
|
||||
float gapError = _wallOffset - gap;
|
||||
if (Mathf.Abs(gapError) > _controller.skinWidth + 0.02f)
|
||||
velocity += _wallNormal * Mathf.Clamp(gapError / dt, -maxPerpSpeed, maxPerpSpeed);
|
||||
float gapError = (_wallOffset + _controller.skinWidth) - gap;
|
||||
float follow = 1f - Mathf.Exp(-wallOffsetFollow * dt);
|
||||
velocity += _wallNormal * Mathf.Clamp(gapError * follow / dt, -maxPerpSpeed, maxPerpSpeed);
|
||||
}
|
||||
|
||||
_controller.Move(velocity * dt);
|
||||
|
||||
Reference in new issue
Block a user