Погоня в радиусе
Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 53 из 71.
Большинство врагов не трогают тебя, пока ты не подойдёшь близко. Измеряй расстояние до игрока на каждом физическом шаге и преследуй его только в пределах заданного радиуса. Эта слизь преследует игрока в пределах 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 запоминает, преследует ли враг игрока, а между двумя радиусами его значение не меняется, поэтому враг продолжает делать то, чем занимался.
Задание
СреднеСделай так, чтобы волк замечал игрока вблизи и сдавался, когда тот далеко.
- В
FixedUpdate()вычисли горизонтальное расстояние до игрока: если оно меньшеnoticeRange, установи полеbool chasingв значениеtrue; если большеgiveUpRange— вfalse. - Пока
chasingравноtrue, направляйrb.linearVelocityк игроку со скоростьюspeed, сохраняя значение по оси y. - В противном случае установи
rb.linearVelocity = new Vector3(0f, rb.linearVelocity.y, 0f);.
Нажми «Играть», подойди к волку и убегай. Затем нажми «Проверить».
Попробуйте сами
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 для физикиСкоростьКинематические телаПовторение: пусковая площадка4Корутины
InvokeInvokeRepeating, CancelInvokeВаша первая корутинаЦиклы в корутинахОстановка корутинПовторение: обратный отсчёт10Проект: Побег с арены
АренаОхотники2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Монетная гонка
Катящийся шарСобираем монетыПотренируйтесь самостоятельно: Песочница Unity