diff --git a/Assets/Scripts/Components/Controller/PlayerCharacterController.cs b/Assets/Scripts/Components/Controller/PlayerCharacterController.cs index a43e198..7e782c9 100644 --- a/Assets/Scripts/Components/Controller/PlayerCharacterController.cs +++ b/Assets/Scripts/Components/Controller/PlayerCharacterController.cs @@ -740,6 +740,21 @@ public class PlayerCharacterController : MonoBehaviour } else if (found) { + // Pinch between two surfaces: the center band can miss the (still touching) climbed + // face and catch a DIFFERENT collider much farther out. Adopting that hit flips the + // normal and the standoff servo drags the capsule across the pinch — oscillating + // every other frame with the span probe snapping it back. When the full-capsule span + // still holds a steep surface meaningfully closer, THAT contact is the climbed face: + // keep it instead of defecting to the far hit. + if (gap > (_controller.skinWidth + 0.05f) * CapsuleScale + && ProbeWallSpan(out Vector3 heldNormal, out float heldGap) + && heldGap + 0.05f * CapsuleScale < gap + && Vector3.Angle(heldNormal, Vector3.up) >= wallMinAngle + && heldNormal.y > CeilingNormalThreshold) + { + probedNormal = heldNormal; + gap = heldGap; + } _wallNormal = probedNormal; _lostContactTimer = 0f; UpdateCeilingClass();