From e3e4f97a6fb120855d856b1145652f709210a0c0 Mon Sep 17 00:00:00 2001 From: swrring Date: Tue, 12 May 2026 16:51:44 +0900 Subject: [PATCH] =?UTF-8?q?fix(BT12-Dev):=20cliffCheck=20=EB=A7=A4=20frame?= =?UTF-8?q?=C2=B7VisualBounds=20=E2=86=92=20SpriteRenderer=20=EC=A0=95?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PD 영역 1: 발판 위 Enemy 가장자리에서 방향 전환 X·한방만 바라보다 떨어짐 PD 영역 2: Player 피격 X 근본: 1. cliffCheck phaseCooldown 가드 - TriggerReverse 시 phaseCooldown=1.0s 설정·이 동안 cliffCheck 비활성 - 발판 끝 회피 후 1초간 cliff 미감지 → KinematicObject 진행 → 발판 밖 → 낙하 2. VisualBounds = Collider.bounds (직전 daad311) - CapsuleCollider 작음 (0.33×0.33)·Player BoxCollider (0.77×1.02) - Intersects 영역 너무 좁아 hit X fix: 1. cliffCheck phaseCooldown 가드 폐기·매 frame 검사 - stuckTimer만 phaseCooldown 가드 유지 (좌우 반복 방지) 2. VisualBounds = Visual.SpriteRenderer.bounds 우선 - sprite 실제 시각 영역·Player 접촉 판정 정합 회귀 영역 X: - IsGrounded 가드·TriggerReverse·KinematicObject 영역 영역 X - Player IsGrounded 조건 유지 (밟기 X·점프 통과 정합) Co-Authored-By: Claude Opus 4.7 (1M context) --- Assets/Scripts/Mechanics/EnemyController.cs | 38 ++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Assets/Scripts/Mechanics/EnemyController.cs b/Assets/Scripts/Mechanics/EnemyController.cs index 15efb9a..631ce6c 100644 --- a/Assets/Scripts/Mechanics/EnemyController.cs +++ b/Assets/Scripts/Mechanics/EnemyController.cs @@ -52,10 +52,10 @@ namespace Platformer.Mechanics public Bounds Bounds => _collider.bounds; /// - /// BT12-Dev 2026-05-12 — Collider Bounds 사용 (PD: Visual 자식 분리 후 sprite bounds 충돌 판정 정합 X). - /// CapsuleCollider2D는 실제 충돌 영역·정확한 Player 접촉 판정. + /// BT12-Dev 2026-05-12 재정정 — SpriteRenderer (Visual) bounds 우선 (PD: Player 피해 X·CapsuleCollider 작음). + /// Visual.SpriteRenderer.bounds = sprite 실제 시각 영역·Player 접촉 판정 정합. /// - public Bounds VisualBounds => _collider != null ? _collider.bounds : (spriteRenderer != null ? spriteRenderer.bounds : new Bounds()); + public Bounds VisualBounds => spriteRenderer != null ? spriteRenderer.bounds : (_collider != null ? _collider.bounds : new Bounds()); PlayerController _cachedPlayer; bool _ignoreCollisionApplied; @@ -320,24 +320,24 @@ namespace Platformer.Mechanics // BT90 — 수평 Raycast 영역 폐기 (BT89 거짓 양성 — 같은 Tile cell 영역 검출) // 벽 영역 = stuckTimer 영역 (50ms 정지 시 즉시 phase+2)으로 처리 - // BT94 — 절벽·벽 검출은 phase cooldown 영역 끝난 후 활성 (좌우 반복 차단) + // BT12-Dev 2026-05-12 — phaseCooldown 가드 폐기 (PD: 한방만 바라보다 떨어짐). + // 매 frame cliffCheck → 발판 끝 즉시 회피·낙하 차단. + if (_collider != null) + { + Vector2 footAhead = 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) + { + TriggerReverse(moveDir, 0.3f); + return; + } + } + if (_phaseCooldown <= 0f) { - // BT96 — 절벽·벽 검출: transform + body 동시 push (가장자리에서 안전 영역으로 즉시 이동) - if (_collider != null) - { - Vector2 footAhead = 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) - { - TriggerReverse(moveDir, 0.3f); - return; - } - } - if (Mathf.Abs(transform.position.x - _lastX) < stuckMoveThreshold) { _stuckTimer += Time.deltaTime;