pgiz3/Assets/Scripts/EnemyAI.cs
2026-03-22 03:00:25 +03:00

110 lines
4.1 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<NavMeshAgent>();
}
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<Rigidbody>();
//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<PlayerHealth>().TakeDamage(10);
}
}
// --- Конец логики выстрела ---
alreadyAttacked = true;
Invoke(nameof(ResetAttack), timeBetweenAttacks);
}
}
private void ResetAttack()
{
alreadyAttacked = false;
}
}