Unity_1lab/1 laba/Assets/Scripts/EnemyAI.cs
2025-09-19 03:17:08 +03:00

202 lines
8.0 KiB
C#
Raw 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;
using UnityEngine.SceneManagement; // Для перезапуска сцены при смерти
public class EnemyAI : MonoBehaviour
{
[Header("Настройки врага")]
public float detectionRange = 10f; // Радиус обнаружения игрока
public float attackRange = 2f; // Дистанция атаки (немедленная смерть)
public float patrolSpeed = 5f; // Скорость патрулирования
public float chaseSpeed = 9f; // Скорость преследования
[Header("Патрульные точки")]
public Transform[] patrolPoints; // Точки для патрулирования
[Header("Звуковые эффекты")]
public AudioClip movementSound; // Звук перемещения (зацикленный)
public AudioClip detectionSound; // Звук обнаружения игрока
public AudioClip killSound; // Звук убийства игрока
private Transform player; // Ссылка на игрока
private NavMeshAgent agent; // Компонент NavMeshAgent
private Animator animator; // Компонент Animator
private AudioSource audioSource; // Компонент AudioSource
private int currentPatrolIndex; // Индекс текущей точки патруля
private enum EnemyState { Patrol, Chase, Attack } // Состояния врага
private EnemyState currentState = EnemyState.Patrol; // Текущее состояние
private bool hasKilledPlayer = false; // Флаг для предотвращения повторного воспроизведения звука убийства
void Start()
{
// Находим компоненты
agent = GetComponent<NavMeshAgent>();
// animator = GetComponent<Animator>();
audioSource = GetComponent<AudioSource>();
player = GameObject.FindGameObjectWithTag("Player").transform; // Убедись, что у игрока есть тег "Player"
// Проверка наличия AudioSource
if (audioSource == null)
{
audioSource = gameObject.AddComponent<AudioSource>();
Debug.LogWarning("AudioSource не был найден, добавлен автоматически.");
}
// Настройка начальных параметров AudioSource
audioSource.playOnAwake = false;
audioSource.loop = true; // Зацикливание для звука перемещения
if (movementSound != null)
{
audioSource.clip = movementSound;
audioSource.Play(); // Начать воспроизведение звука перемещения
}
// Настройка начальных параметров NavMeshAgent
agent.speed = patrolSpeed;
// Устанавливаем начальное состояние
if (patrolPoints.Length > 0)
{
agent.SetDestination(patrolPoints[currentPatrolIndex].position);
}
}
void Update()
{
// Проверяем дистанцию до игрока
float distanceToPlayer = Vector3.Distance(transform.position, player.position);
// Определяем состояние врага
if (distanceToPlayer <= attackRange)
{
if (currentState != EnemyState.Attack)
{
// Останавливаем все текущие звуки при входе в состояние атаки
if (audioSource.isPlaying)
{
audioSource.Stop();
}
}
currentState = EnemyState.Attack;
}
else if (distanceToPlayer <= detectionRange)
{
if (currentState != EnemyState.Chase)
{
if (detectionSound != null && audioSource.clip != detectionSound)
{
audioSource.Stop(); // Останавливаем текущий звук
audioSource.loop = true; // Зацикливание для звука преследования
audioSource.clip = detectionSound;
audioSource.Play(); // Начать воспроизведение звука преследования
}
}
currentState = EnemyState.Chase;
}
else
{
if (currentState != EnemyState.Patrol)
{
// Останавливаем звук преследования и возвращаемся к звуку перемещения
if (audioSource.clip == detectionSound)
{
audioSource.Stop();
if (movementSound != null)
{
audioSource.clip = movementSound;
audioSource.Play();
}
}
}
currentState = EnemyState.Patrol;
}
// Выполняем действия в зависимости от состояния
switch (currentState)
{
case EnemyState.Patrol:
Patrol();
break;
case EnemyState.Chase:
ChasePlayer();
break;
case EnemyState.Attack:
KillPlayer();
break;
}
UpdateMovementSound();
}
void Patrol()
{
agent.speed = patrolSpeed; // Устанавливаем скорость патрулирования
// Если враг достиг точки патруля, выбираем следующую
if (!agent.pathPending && agent.remainingDistance < 0.5f)
{
currentPatrolIndex = (currentPatrolIndex + 1) % patrolPoints.Length;
agent.SetDestination(patrolPoints[currentPatrolIndex].position);
}
}
void ChasePlayer()
{
agent.speed = chaseSpeed; // Устанавливаем скорость преследования
agent.SetDestination(player.position); // Идём к игроку
}
void KillPlayer()
{
agent.SetDestination(transform.position); // Останавливаем движение
// Воспроизводим звук убийства только один раз
if (killSound != null && !hasKilledPlayer)
{
audioSource.PlayOneShot(killSound);
hasKilledPlayer = true; // Устанавливаем флаг
}
// Немедленная смерть игрока
Debug.Log("Игрок убит!");
// Перезапускаем сцену (или показываем экран смерти)
GameUIManager uiManager = FindObjectOfType<GameUIManager>();
if (uiManager != null)
{
uiManager.ShowDeathScreen();
}
else
{
Debug.LogError("GameUIManager не найден в сцене!");
}
}
void UpdateMovementSound()
{
// Включаем/выключаем звук перемещения только в состоянии Patrol
if (movementSound != null && audioSource != null && audioSource.clip == movementSound && currentState == EnemyState.Patrol)
{
if (agent.velocity.magnitude > 0.1f && !audioSource.isPlaying)
{
audioSource.Play();
}
else if (agent.velocity.magnitude <= 0.1f && audioSource.isPlaying)
{
audioSource.Stop();
}
}
}
void OnDrawGizmosSelected()
{
// Радиус обнаружения
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, detectionRange);
// Радиус атаки
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, attackRange);
}
}