Преследование в пределах досягаемости
Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 51 из 63.
Большинство врагов не трогают тебя, пока ты не подойдёшь близко. Измеряй расстояние до игрока на каждом физическом шаге и преследуй его только в пределах определённой дальности. Эта слизь преследует игрока в пределах sightRange и стоит на месте за её пределами:
void FixedUpdate()
{
Vector3 toPlayer = player.position - rb.position;
toPlayer.y = 0f;
if (toPlayer.magnitude < sightRange)
{
Vector3 dir = toPlayer.normalized;
rb.linearVelocity = new Vector3(dir.x * speed, rb.linearVelocity.y, dir.z * speed);
}
else
{
rb.linearVelocity = new Vector3(0f, rb.linearVelocity.y, 0f);
}
}else здесь важен: Rigidbody сохраняет скорость, пока что-нибудь её не изменит. Без него слизь, потерявшая тебя из виду, продолжит скользить, пока трение её не остановит, а на льду она не остановится никогда. Поскольку сначала y было присвоено значение 0, toPlayer.magnitude — это расстояние по земле, поэтому игрок, стоящий на ящике рядом со слизью, всё равно считается находящимся рядом с ней.
У одной дальности есть слабое место. Игрок, стоящий на её границе, то оказывается внутри неё, то выходит за неё, и слизь снова и снова начинает движение и останавливается. Враги избегают этого, используя две дальности: они замечают игрока в пределах короткой дальности и сдаются, только когда тот оказывается за пределами более длинной. bool запоминает, преследует ли враг игрока, а между двумя дальностями его значение не меняется, поэтому враг продолжает делать то, что делал.
Задание
СреднеВолк охотится в лесу. Напиши скрипт Wolf для волка. В Inspector задай ему player, speed (3), noticeRange (4) и giveUpRange (8). Скрипт Player уже готов.
- Поле типа
boolс именемchasingуказывает, преследует ли волк игрока. Изначально оно равноfalse. - На каждом шаге физики измеряй расстояние до игрока по земле (без учета высоты). Если расстояние меньше
noticeRange:chasingстановится равнымtrue. Если большеgiveUpRange: оно становится равнымfalse. Между этими значениями оно не меняется. - Во время преследования волк бежит к игроку со скоростью
speed, используя свой Rigidbody и сохраняя скорость по оси y. В противном случае он стоит на месте: скорость по осям x и z равна 0.
Нажми Play, подойди к волку и убеги, затем нажми Check.
Попробуйте сами
using UnityEngine;
public class Wolf : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private float speed = 3f;
[SerializeField] private float noticeRange = 4f;
[SerializeField] private float giveUpRange = 8f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
// заметить игрока, прекратить преследование и гнаться за ним или стоять на месте
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Физика и игровой процесс
1Твёрдое тело
Гравитация и массаТолкаем с помощью AddForceПрыжок с импульсомFixedUpdate для физикиСкоростьКинематические телаПовторение: пусковая площадка2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Погоня за монетами
Катящийся мячМонеты для сбора3Триггеры
Триггерные коллайдерыOnTriggerEnterПодбираемые предметыЗоны гибелиВход и выходПовторение: ключ и дверь6Рейкасты
Physics.RaycastRaycastHitПроверка земли с помощью лучаСлои и LayerMaskЛиния видимостиOverlapSphere и SphereCastПовторение: лазерная растяжка9Враги
Преследование игрокаПреследование в пределах досягаемостиПатрулирование и преследованиеЗдоровье и уронОтбрасываниеПовторение: сторожевой пёс