diff --git a/Assets/Scripts/Mechanics/PlayerController.cs b/Assets/Scripts/Mechanics/PlayerController.cs index 8bc7153..ebd0c06 100644 --- a/Assets/Scripts/Mechanics/PlayerController.cs +++ b/Assets/Scripts/Mechanics/PlayerController.cs @@ -251,10 +251,18 @@ namespace Platformer.Mechanics bool standingOnPlatform = false; if (collider2d != null && !isJumpingThrough) { - Vector2 footPos = new Vector2(collider2d.bounds.center.x, collider2d.bounds.min.y + 0.02f); + // BT73 — footHit Raycast 3점 (좌·중·우) (PD 보고 2026-05-08: 발판 가장자리 jitter) + // 단일 중앙 Raycast 시 가장자리 영역 검출 X·검출 O frame 교차 → 밀려남 + // 좌·중·우 3점 어느 하나라도 검출 시 standingOnPlatform=true → 안정 + float footY = collider2d.bounds.min.y + 0.02f; + float boundsLeft = collider2d.bounds.min.x + 0.02f; + float boundsCenter = collider2d.bounds.center.x; + float boundsRight = collider2d.bounds.max.x - 0.02f; int jumpThroughMask = 1 << JUMP_THROUGH_LAYER; - RaycastHit2D footHit = Physics2D.Raycast(footPos, Vector2.down, 0.1f, jumpThroughMask); - standingOnPlatform = footHit.collider != null; + RaycastHit2D footHitC = Physics2D.Raycast(new Vector2(boundsCenter, footY), Vector2.down, 0.1f, jumpThroughMask); + RaycastHit2D footHitL = Physics2D.Raycast(new Vector2(boundsLeft, footY), Vector2.down, 0.1f, jumpThroughMask); + RaycastHit2D footHitR = Physics2D.Raycast(new Vector2(boundsRight, footY), Vector2.down, 0.1f, jumpThroughMask); + standingOnPlatform = footHitC.collider != null || footHitL.collider != null || footHitR.collider != null; } // standingOnPlatform=true → Layer 16 ON (착지·서있는 영역 영역 X) / 그 외 → Layer 16 OFF (통과)