From a4bf5086deb308d5a65c6048cda90787a1c72245 Mon Sep 17 00:00:00 2001 From: swrring Date: Tue, 12 May 2026 17:01:00 +0900 Subject: [PATCH] =?UTF-8?q?fix(BT12-Dev):=20cliffCheck=20footAhead=20Enemy?= =?UTF-8?q?=20=EC=98=81=EC=97=AD=20=EC=83=81=EB=8C=80=20(=EA=B0=80?= =?UTF-8?q?=EC=9E=A5=EC=9E=90=EB=A6=AC=20=EA=B1=B8=EC=B3=90=20=EB=8C=80?= =?UTF-8?q?=EA=B8=B0=20=EC=A0=95=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PD: "발판 가장자리 걸쳐 방향 전환 X·영구 대기" 근본: - cliffCheckDistance=1.0 절대값 사용 - Type1 발판 폭 1.54·반=0.77 < cliffCheckDistance 1.0 - Enemy bounds.center가 발판 안에 있어도 ±1.0 unit footAhead는 양측 발판 밖 - → 양측 cliff 검출 → 영구 대기 fix: - footAhead = bounds.center + moveDir * (bounds.extents.x + 0.15) - Enemy 영역 가장자리 + 0.15 unit 마진 (Enemy 실제 발이 닿는 위치) - Enemy 발판 안 → 전방만 cliff → TriggerReverse·정상 방향 전환 - Enemy 발판 가장자리 (extents 밖) → 양측 cliff → 제자리 대기 (좁은 발판) 회귀 영역 X: - IsGrounded 가드·매 frame cliffCheck·2D AABB Player 피격 영역 영역 X Co-Authored-By: Claude Opus 4.7 (1M context) --- Assets/Scripts/Mechanics/EnemyController.cs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/Assets/Scripts/Mechanics/EnemyController.cs b/Assets/Scripts/Mechanics/EnemyController.cs index 2abbb06..56fe9b1 100644 --- a/Assets/Scripts/Mechanics/EnemyController.cs +++ b/Assets/Scripts/Mechanics/EnemyController.cs @@ -320,23 +320,19 @@ namespace Platformer.Mechanics // BT90 — 수평 Raycast 영역 폐기 (BT89 거짓 양성 — 같은 Tile cell 영역 검출) // 벽 영역 = stuckTimer 영역 (50ms 정지 시 즉시 phase+2)으로 처리 - // BT12-Dev 2026-05-12 — cliffCheck 매 frame + 양측 검사 (PD: 발판 폭 좁을 시 제자리 대기) + // BT12-Dev 2026-05-12 — cliffCheck Enemy 영역 가장자리 상대 (PD: 발판 가장자리 걸쳐 대기 정정) + // 절대 cliffCheckDistance 폐기·bounds.extents.x + edgeMargin 사용 → Enemy 영역 바로 앞 검사 if (_collider != null) { - Vector2 footAheadFwd = new Vector2( - _collider.bounds.center.x + moveDir * cliffCheckDistance, - _collider.bounds.min.y + 0.05f - ); - RaycastHit2D groundHitFwd = Physics2D.Raycast(footAheadFwd, Vector2.down, cliffCheckDepth, groundLayerMask); + const float EDGE_MARGIN = 0.15f; + float fwdX = _collider.bounds.center.x + moveDir * (_collider.bounds.extents.x + EDGE_MARGIN); + float backX = _collider.bounds.center.x - moveDir * (_collider.bounds.extents.x + EDGE_MARGIN); + float footY = _collider.bounds.min.y + 0.05f; + RaycastHit2D groundHitFwd = Physics2D.Raycast(new Vector2(fwdX, footY), Vector2.down, cliffCheckDepth, groundLayerMask); if (groundHitFwd.collider == null) { - // 전방 cliff — 반대편도 검사. 반대편도 cliff면 발판 폭 좁음 → 제자리 대기. - Vector2 footAheadBack = new Vector2( - _collider.bounds.center.x - moveDir * cliffCheckDistance, - _collider.bounds.min.y + 0.05f - ); - RaycastHit2D groundHitBack = Physics2D.Raycast(footAheadBack, Vector2.down, cliffCheckDepth, groundLayerMask); + RaycastHit2D groundHitBack = Physics2D.Raycast(new Vector2(backX, footY), Vector2.down, cliffCheckDepth, groundLayerMask); if (groundHitBack.collider == null) { // 양측 cliff — 제자리 대기 @@ -345,7 +341,6 @@ namespace Platformer.Mechanics _stuckTimer = 0f; return; } - // 전방만 cliff — 방향 전환 TriggerReverse(moveDir, 0.3f); return; }