using System.Collections; using UnityEngine; using UnityEngine.AI; public class EnemyMovement : MonoBehaviour { [Header("Navigation")] public NavMeshAgent agent; public Transform player; public float updatePathInterval = 0.5f; public float roomCheckInterval = 2f; [Header("Combat")] public float attackRange = 2f; public float attackCooldown = 1f; public float sightRange = 20f; public float patrolRange = 5f; private bool canAttack = true; private enum EnemyState { Patrolling, Chasing, Attacking } private EnemyState currentState = EnemyState.Patrolling; private Vector3 patrolCenter; private Vector3 patrolTarget; [Header("Animation")] public Animator animator; private void Start() { // Najdi hráče GameObject playerObject = GameObject.FindWithTag("Player"); if (playerObject != null) { player = playerObject.transform; } // Nastav výchozí pozice patrolCenter = transform.position; GenerateNewPatrolTarget(); // Spustit coroutines if (agent != null) { agent.stoppingDistance = attackRange - 0.2f; StartCoroutine(UpdatePath()); StartCoroutine(CheckPlayerInRange()); StartCoroutine(CheckCurrentRoom()); } } private void Update() { if (agent == null) return; // Update animací if (animator != null) { animator.SetFloat("Speed", agent.velocity.magnitude); } // Stavové chování switch (currentState) { case EnemyState.Patrolling: PatrolBehavior(); break; case EnemyState.Chasing: ChaseBehavior(); break; case EnemyState.Attacking: AttackBehavior(); break; } } private void PatrolBehavior() { // Pokud je cíl patrolování dosažen, vyber nový cíl if (!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance) { GenerateNewPatrolTarget(); } } private void ChaseBehavior() { if (player == null) { currentState = EnemyState.Patrolling; return; } float distanceToPlayer = Vector3.Distance(transform.position, player.position); if (distanceToPlayer <= attackRange) { currentState = EnemyState.Attacking; agent.isStopped = true; } else if (distanceToPlayer > sightRange * 1.5f) { // Hráč je příliš daleko, vrať se k patrolování currentState = EnemyState.Patrolling; GenerateNewPatrolTarget(); } } private void AttackBehavior() { if (player == null) { currentState = EnemyState.Patrolling; agent.isStopped = false; return; } float distanceToPlayer = Vector3.Distance(transform.position, player.position); // Otoč se k hráči Vector3 directionToPlayer = (player.position - transform.position).normalized; Quaternion targetRotation = Quaternion.LookRotation(new Vector3(directionToPlayer.x, 0, directionToPlayer.z)); transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 5f * Time.deltaTime); // Útok na hráče if (canAttack && distanceToPlayer <= attackRange) { StartCoroutine(Attack()); } // Pokud je hráč příliš daleko, pokračuj v pronásledování if (distanceToPlayer > attackRange * 1.2f) { currentState = EnemyState.Chasing; agent.isStopped = false; } } private IEnumerator UpdatePath() { while (true) { if (currentState == EnemyState.Chasing && player != null) { agent.SetDestination(player.position); } else if (currentState == EnemyState.Patrolling) { agent.SetDestination(patrolTarget); } yield return new WaitForSeconds(updatePathInterval); } } private IEnumerator CheckPlayerInRange() { while (true) { if (player != null && currentState != EnemyState.Attacking) { float distanceToPlayer = Vector3.Distance(transform.position, player.position); if (distanceToPlayer <= sightRange && distanceToPlayer > attackRange) { currentState = EnemyState.Chasing; } else if (distanceToPlayer <= attackRange) { currentState = EnemyState.Attacking; agent.isStopped = true; } } yield return new WaitForSeconds(0.5f); } } private IEnumerator CheckCurrentRoom() { while (true) { // Zkontroluj, zda je enemy stále v platné místnosti if (!agent.isOnNavMesh) { Debug.LogWarning("Enemy is off NavMesh, attempting to warp..."); agent.Warp(transform.position); } yield return new WaitForSeconds(roomCheckInterval); } } private void GenerateNewPatrolTarget() { // Vyber náhodný cíl v okolí výchozí pozice Vector2 randomCircle = Random.insideUnitCircle * patrolRange; patrolTarget = patrolCenter + new Vector3(randomCircle.x, 0, randomCircle.y); // Zajisti, že cíl je na NavMesh NavMeshHit hit; if (NavMesh.SamplePosition(patrolTarget, out hit, patrolRange, NavMesh.AllAreas)) { patrolTarget = hit.position; } } private IEnumerator Attack() { canAttack = false; // Spustit animaci útoku if (animator != null) { animator.SetTrigger("Attack"); } // Zde můžeš přidat logiku poškození hráče Debug.Log("Enemy attacks player!"); yield return new WaitForSeconds(attackCooldown); canAttack = true; } // Voláno při smrti nepřítele public void Die() { StopAllCoroutines(); if (agent != null) { agent.isStopped = true; } // Zde můžeš přidat animaci smrti atd. Destroy(gameObject, 2f); } // Pro vizualizaci v editoru private void OnDrawGizmosSelected() { Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, attackRange); Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(transform.position, sightRange); Gizmos.color = Color.blue; Gizmos.DrawWireSphere(patrolCenter, patrolRange); if (Application.isPlaying) { Gizmos.color = Color.green; Gizmos.DrawSphere(patrolTarget, 0.3f); Gizmos.DrawLine(transform.position, patrolTarget); } } }