From 4c5e33ab46960ee413eedce7c7541a521e13c648 Mon Sep 17 00:00:00 2001 From: swrring Date: Tue, 12 May 2026 16:58:29 +0900 Subject: [PATCH] =?UTF-8?q?fix(BT12-Dev):=20cliffCheck=20=EC=96=91?= =?UTF-8?q?=EC=B8=A1=20=EA=B2=80=EC=82=AC=C2=B7=EB=B0=9C=ED=8C=90=20?= =?UTF-8?q?=ED=8F=AD=20=EC=A2=81=EC=9D=84=20=EC=8B=9C=20=EC=A0=9C=EC=9E=90?= =?UTF-8?q?=EB=A6=AC=20=EB=8C=80=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PD: "발판과 같이 떨어질 수 있는 위치 가장자리에서 방향 바꿔서 정상 patrol·순찰 범위 너무 짧으면 제자리 대기" 근본: - 전방 cliffCheck만 검사 → 발판 폭이 Enemy 영역 2배 미만일 때 - TriggerReverse → 반대편도 cliff → 다시 TriggerReverse → 좌우 영구 반복 fix: - 전방 cliff 감지 시 반대편(-moveDir)도 추가 검사 - 전방만 cliff → TriggerReverse (방향 전환·정상 patrol) - 양측 cliff → 발판 폭 좁음 → 제자리 대기 (move.x=0·waitTimer 재설정) 회귀 영역 X: - IsGrounded 가드·매 frame cliffCheck·KinematicObject·2D AABB 영역 영역 X Co-Authored-By: Claude Opus 4.7 (1M context) --- Assets/Scripts/Mechanics/EnemyController.cs | 25 ++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Assets/Scripts/Mechanics/EnemyController.cs b/Assets/Scripts/Mechanics/EnemyController.cs index 6435215..2abbb06 100644 --- a/Assets/Scripts/Mechanics/EnemyController.cs +++ b/Assets/Scripts/Mechanics/EnemyController.cs @@ -320,17 +320,32 @@ namespace Platformer.Mechanics // BT90 — 수평 Raycast 영역 폐기 (BT89 거짓 양성 — 같은 Tile cell 영역 검출) // 벽 영역 = stuckTimer 영역 (50ms 정지 시 즉시 phase+2)으로 처리 - // BT12-Dev 2026-05-12 — phaseCooldown 가드 폐기 (PD: 한방만 바라보다 떨어짐). - // 매 frame cliffCheck → 발판 끝 즉시 회피·낙하 차단. + // BT12-Dev 2026-05-12 — cliffCheck 매 frame + 양측 검사 (PD: 발판 폭 좁을 시 제자리 대기) if (_collider != null) { - Vector2 footAhead = new Vector2( + Vector2 footAheadFwd = new Vector2( _collider.bounds.center.x + moveDir * cliffCheckDistance, _collider.bounds.min.y + 0.05f ); - RaycastHit2D groundHit = Physics2D.Raycast(footAhead, Vector2.down, cliffCheckDepth, groundLayerMask); - if (groundHit.collider == null) + RaycastHit2D groundHitFwd = Physics2D.Raycast(footAheadFwd, 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); + if (groundHitBack.collider == null) + { + // 양측 cliff — 제자리 대기 + if (control != null) control.move.x = 0f; + _waitTimer = Random.Range(waitMinTime, waitMaxTime); + _stuckTimer = 0f; + return; + } + // 전방만 cliff — 방향 전환 TriggerReverse(moveDir, 0.3f); return; }