using UnityEngine; using System; public enum EnemyState { Patrol, Investigate, Chase, Stunned } public class EnemyAI : Character { [SerializeField] private float _patrolSpeed = 1f; [SerializeField] private float _patrolRange = 5f; [SerializeField] private float _investigateRange = 8f; [SerializeField] private float _chaseRange = 10f; [SerializeField] private float _stunDuration = 1f; [SerializeField] private bool _debugMode = false; private EnemyState _currentState = EnemyState.Patrol; private Vector3 _patrolTarget; private Vector3 _investigatePosition; private float _stunTimer = 0f; private float _patrolDirection = 1f; [SerializeField] private Character _player = null; public EnemyState CurrentState => _currentState; protected override void SetClimbingAnimation(bool isClimbing) { // Implement climbing animation if needed } protected override void SetWalkingAnimation(bool isWalking) { _animator.SetBool("Walk", isWalking); } private void Start() { _patrolTarget = transform.position; SetState(EnemyState.Patrol); } private void Update() { // Update stun timer if (_currentState == EnemyState.Stunned) { _stunTimer -= Time.deltaTime; if (_stunTimer <= 0f) { SetState(EnemyState.Patrol); } return; } // Get player position if available var player = _player; if (player == null) { HandlePatrol(); return; } float distanceToPlayer = Vector3.Distance(transform.position, player.transform.position); // State transitions switch (_currentState) { case EnemyState.Patrol: if (distanceToPlayer < _investigateRange) { SetState(EnemyState.Chase); } else { HandlePatrol(); } break; case EnemyState.Investigate: if (distanceToPlayer < _chaseRange) { SetState(EnemyState.Chase); } else if (Vector3.Distance(transform.position, _investigatePosition) < 0.5f) { SetState(EnemyState.Patrol); } else { HandleInvestigate(); } break; case EnemyState.Chase: if (distanceToPlayer > _chaseRange) { SetState(EnemyState.Patrol); } else { HandleChase(player.transform.position); } break; } } private void SetState(EnemyState newState) { if (_currentState == newState) return; if (_debugMode) Debug.Log($"[EnemyAI] State changed: {_currentState} -> {newState}"); _currentState = newState; } private void HandlePatrol() { // Simple back-and-forth patrol if (Vector3.Distance(transform.position, _patrolTarget) < 0.3f) { _patrolDirection *= -1f; _patrolTarget = transform.position + Vector3.right * _patrolRange * _patrolDirection; } float direction = _patrolTarget.x > transform.position.x ? 1f : -1f; MoveTo(direction * _patrolSpeed, 0f); } private void HandleInvestigate() { float direction = _investigatePosition.x > transform.position.x ? 1f : -1f; MoveTo(direction * _patrolSpeed, 0f); } private void HandleChase(Vector3 playerPosition) { float direction = playerPosition.x > transform.position.x ? 1f : -1f; MoveTo(direction * _patrolSpeed, 0f); } public void OnNoise(Vector3 noisePosition) { if (_currentState == EnemyState.Stunned) return; if (_currentState != EnemyState.Chase) { _investigatePosition = noisePosition; SetState(EnemyState.Investigate); if (_debugMode) Debug.Log($"[EnemyAI] Investigating noise at {noisePosition}"); } } public void OnHitByHammer(float stunDuration) { _stunTimer = stunDuration; SetState(EnemyState.Stunned); if (_debugMode) Debug.Log($"[EnemyAI] Stunned for {stunDuration} seconds"); } }