using UnityEngine; using UnityEngine.AI; // Важно: добавляем пространство имен для работы с NavMesh public class EnemyAI : MonoBehaviour { public NavMeshAgent agent; public Transform player; public LayerMask whatIsGround, whatIsPlayer; // Патрулирование public Vector3 walkPoint; bool walkPointSet; public float walkPointRange; // Атака public float timeBetweenAttacks; bool alreadyAttacked; public GameObject projectile; // Враг будет стрелять объектами, а не рэйкастом для наглядности // Состояния public float sightRange, attackRange; public bool playerInSightRange, playerInAttackRange; private void Awake() { player = GameObject.Find("Player").transform; // Находим игрока по имени agent = GetComponent(); } private void Update() { // Проверяем, находится ли игрок в зоне видимости и в зоне атаки playerInSightRange = Physics.CheckSphere(transform.position, sightRange, whatIsPlayer); playerInAttackRange = Physics.CheckSphere(transform.position, attackRange, whatIsPlayer); if (!playerInSightRange && !playerInAttackRange) Patroling(); if (playerInSightRange && !playerInAttackRange) ChasePlayer(); if (playerInAttackRange && playerInSightRange) AttackPlayer(); } private void Patroling() { if (!walkPointSet) SearchWalkPoint(); if (walkPointSet) agent.SetDestination(walkPoint); Vector3 distanceToWalkPoint = transform.position - walkPoint; // Точка достигнута if (distanceToWalkPoint.magnitude < 1f) walkPointSet = false; } private void SearchWalkPoint() { // Ищем случайную точку в заданном диапазоне float randomZ = Random.Range(-walkPointRange, walkPointRange); float randomX = Random.Range(-walkPointRange, walkPointRange); walkPoint = new Vector3(transform.position.x + randomX, transform.position.y, transform.position.z + randomZ); // Проверяем, находится ли точка на NavMesh if (Physics.Raycast(walkPoint, -transform.up, 2f, whatIsGround)) walkPointSet = true; } private void ChasePlayer() { agent.SetDestination(player.position); } private void AttackPlayer() { // Враг останавливается и смотрит на игрока agent.SetDestination(transform.position); transform.LookAt(player); if (!alreadyAttacked) { // --- Логика выстрела --- // Создаем снаряд в точке выстрела (например, перед врагом) //Rigidbody rb = Instantiate(projectile, transform.position + transform.forward, Quaternion.identity).GetComponent(); //rb.AddForce(transform.forward * 32f, ForceMode.Impulse); //rb.AddForce(transform.up * 4f, ForceMode.Impulse); // Небольшой подброс для параболы // Вместо стрельбы объектами, для простоты используем рэйкаст, как у игрока RaycastHit hit; if (Physics.Raycast(transform.position, transform.forward, out hit, attackRange)) { if (hit.transform.CompareTag("Player")) { Debug.Log("Враг попал в игрока!"); // Наносим урон игроку hit.transform.GetComponent().TakeDamage(10); } } // --- Конец логики выстрела --- alreadyAttacked = true; Invoke(nameof(ResetAttack), timeBetweenAttacks); } } private void ResetAttack() { alreadyAttacked = false; } }