/
against
/
AIEnemyUnity
Обзор
Документация
Войти
/
against
/
AIEnemyUnity
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
AdvancedMovementController.cs
144 строки
6 KB
Северьянов Святослав
Добавлен скрипт перемещения
27 апр 2025, 14:48
27 апр 2025, 14:48
cae562f
Код
Авторство
О чём код?
using UnityEngine; using UnityEngine.AI; public class AdvancedMovementController : MonoBehaviour { public Transform player; // Игрок public float patrolSpeed = 2f; // Скорость патрулирования public float minDistance = 3f; // Минимальное расстояние, при котором враг отступает public float maxDistance = 10f; // Максимальное расстояние, при котором враг приближается public Animator animator; // Анимационная машина персонажа private NavMeshAgent agent; // Навигационный агент private bool isAvoiding = false; // Признак того, что враг убегает private bool isApproaching = false; // Признак того, что враг приближается private float lastUpdateTime; // Время последнего обновления направления public float turnSpeed = 3f; private bool wasTurning = false; private float lastDecisionTime; // Время последнего решения public float decisionInterval = 1f; // Интервал принятия решений void Start() { agent = GetComponent<NavMeshAgent>(); agent.speed = patrolSpeed; agent.autoBraking = false; // Отключаем автоматическое торможение lastDecisionTime = Time.time; } void Update() { // Периодически принимаем решение о новом направлении if(Time.time - lastDecisionTime > decisionInterval) { EvaluateSituation(); lastDecisionTime = Time.time; } // Обновляем анимацию UpdateAnimator(); SmoothlyRotateTowardsTarget(); } void EvaluateSituation() { // Оцениваем расстояние до игрока float distanceToPlayer = Vector3.Distance(transform.position, player.position); // Анализируем ситуацию if(distanceToPlayer < minDistance) { AvoidPlayer(); // Если игрок слишком близко, убегаем } else if(distanceToPlayer > maxDistance) { ApproachPlayer(); // Если игрок слишком далеко, приближаемся } else { RandomRoaming(); // Свободное перемещение } } void AvoidPlayer() { if(!isAvoiding) { isAvoiding = true; isApproaching = false; } // Бегство от игрока Vector3 runAwayDirection = (transform.position - player.position).normalized; agent.SetDestination(transform.position + runAwayDirection * minDistance); } void ApproachPlayer() { if(!isApproaching) { isApproaching = true; isAvoiding = false; } // Прорывание к игроку agent.SetDestination(player.position); } void RandomRoaming() { if(isAvoiding || isApproaching) { isAvoiding = false; isApproaching = false; } // Случайное направление каждые n секунд float sideways = Random.Range(-1f, 1f); // Слева-направо float forwards = Random.Range(-1f, 1f); // Вперед-назад Vector3 roamingDirection = new Vector3(sideways, 0f, forwards).normalized; // Ставим точку назначения рядом с текущим положением agent.SetDestination(transform.position + roamingDirection * 5f); } void UpdateAnimator() { // Получаем направление движения агента Vector3 agentVelocity = agent.velocity; Vector3 movementDirection = agentVelocity.normalized; // Передаем направление движения в Animator animator.SetBool("isMove", true); animator.SetFloat("VelocityX", movementDirection.x); animator.SetFloat("VelocityY", movementDirection.z); } void SmoothlyRotateTowardsTarget() { // Вектор направления на игрока Vector3 directionToTarget = (player.position - transform.position).normalized; // Целевое вращение Quaternion targetRotation = Quaternion.LookRotation(directionToTarget); // Проверяем, изменился ли угол поворота bool turningNow = Quaternion.Angle(transform.rotation, targetRotation) > 1f; // Если начался поворот, определяем направление if(wasTurning != turningNow && turningNow) { // Определяем направление поворота float dotProduct = Vector3.Dot(transform.right, directionToTarget); string triggerName = dotProduct > 0 ? "TurnRight" : "TurnLeft"; // Отправляем соответствующий триггер animator.SetTrigger(triggerName); } // Обновляем статус поворота wasTurning = turningNow; // Плавно поворачиваем персонаж transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, turnSpeed * Time.deltaTime); } }