diff --git a/Assets/Scripts/Mechanics/EnemyController.cs b/Assets/Scripts/Mechanics/EnemyController.cs index 27909a2..45865f3 100644 --- a/Assets/Scripts/Mechanics/EnemyController.cs +++ b/Assets/Scripts/Mechanics/EnemyController.cs @@ -29,7 +29,8 @@ namespace Platformer.Mechanics public float cliffCheckDistance = 0.6f; // 발 앞 절벽 검출 거리 public float cliffCheckDepth = 1.5f; // 발 아래 Raycast 거리 (BT81: 0.8→1.5 — 깊게 검출) public LayerMask groundLayerMask = (1 << 0) | (1 << 16); // BT81: Layer 0 (지면) + Layer 16 (발판) — Enemy/Player 거짓 양성 차단 - public float stuckThresholdTime = 0.5f; // 벽 정지 검출 시간 (BT81) + public float stuckThresholdTime = 0.3f; // 벽 정지 검출 시간 (BT83: 0.5→0.3 — 빠른 영역 전환) + public float wallCheckDistance = 0.5f; // BT83: 수평 벽 Raycast 거리 (벽 가장자리 미세 밀림 차단) private float _startX; private float _targetX; @@ -131,6 +132,25 @@ namespace Platformer.Mechanics } _lastX = transform.position.x; + // BT83 — 수평 벽 검출 (PD 보고 2026-05-08): 벽 가장자리 미세 밀림 → 절벽 떨어짐 차단 + // 발 영역 horizontal Raycast Layer 0+16 검출 시 = 벽 → 다음 phase 즉시 강제 + if (Mathf.Abs(dx) > patrolArriveThreshold && _collider != null) + { + Vector2 wallOrigin = new Vector2( + _collider.bounds.center.x + moveDir * 0.05f, + _collider.bounds.center.y + ); + RaycastHit2D wallHit = Physics2D.Raycast(wallOrigin, new Vector2(moveDir, 0), wallCheckDistance, groundLayerMask); + if (wallHit.collider != null) + { + _patrolPhase = (_patrolPhase + 1) % 4; + SetNextPatrolTarget(); + dx = _targetX - transform.position.x; + moveDir = Mathf.Sign(dx); + _stuckTimer = 0f; + } + } + // 절벽 검출 — 발 앞 영역 Raycast 지면 X 시 시작 위치로 즉시 복귀 if (Mathf.Abs(dx) > patrolArriveThreshold && _collider != null) {