Menu
CoddyTech

Патрулирование и преследование

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 52 из 63.

Патрульный страж проходит маршрут, пока не замечает игрока, преследует его и возвращается на маршрут, когда игрок исчезает. Оба поведения направляют стража одинаково — к точке, поэтому для перемещения в обоих случаях можно использовать один метод. Этот часовой ходит туда-сюда между двумя постами и преследует игрока в пределах chaseRange:

[SerializeField] private Transform pointA;
[SerializeField] private Transform pointB;
[SerializeField] private Transform player;
[SerializeField] private float speed = 2f;
[SerializeField] private float chaseRange = 5f;
private Rigidbody rb;
private Transform goal;

void Start()
{
    rb = GetComponent<Rigidbody>();
    goal = pointA;
}

void FixedUpdate()
{
    if (Flat(player.position - rb.position).magnitude < chaseRange)
    {
        WalkTo(player.position);
        return;
    }
    if (Flat(goal.position - rb.position).magnitude < 0.2f)
    {
        goal = goal == pointA ? pointB : pointA;
    }
    WalkTo(goal.position);
}

void WalkTo(Vector3 target)
{
    Vector3 dir = Flat(target - rb.position).normalized;
    rb.linearVelocity = new Vector3(dir.x * speed, rb.linearVelocity.y, dir.z * speed);
}

Vector3 Flat(Vector3 v)
{
    return new Vector3(v.x, 0f, v.z);
}

Сначала выполняется проверка для преследования, а команда return пропускает код патрулирования, поэтому при приближении игрока страж всегда переключается на преследование. goal — это поле, поэтому страж помнит его значение во время преследования: когда игрок исчезнет, страж продолжит путь к посту, к которому направлялся.

Проверка прибытия измеряет расстояние по земле. Посты — это маркеры на полу, а центр стража находится на 1 единицу выше них, поэтому расстояние с учётом высоты никогда не станет меньше 1, и страж никогда не развернётся. Проверка требует расстояние меньше 0.2, а не ровно 0: при скорости 2 единицы в секунду страж перемещается на 0.04 единицы за шаг и почти никогда не оказывается точно у поста.

challenge icon

Задание

Средне

Охранный робот патрулирует склад. Напиши скрипт Robot. Инспектор передаёт ему waypoints (четыре жёлтых маркера W0–W3 по порядку), player, speed (4) и chaseRange (4). Скрипт Player готов.

  • Поле int с именем next, начинающееся с 0, — это индекс контрольной точки, к которой движется робот.
  • Патрулирование: двигайся к waypoints[next]. Как только робот окажется ближе чем на 0.2 к ней по земле, переключи next на следующую контрольную точку, а после последней — обратно на 0.
  • Погоня: пока игрок находится ближе, чем на chaseRange по земле, двигайся к игроку.
  • Когда игрок отдалится, продолжай двигаться к waypoints[next] — контрольной точке, к которой робот направлялся.
  • Перемещайся, задавая скорость Rigidbody на speed по земле и сохраняя скорость по оси y.

Нажми Play, посмотри один круг патрулирования и пересеки путь робота, затем нажми Check.

Попробуйте сами

using UnityEngine;

public class Robot : MonoBehaviour
{
    [SerializeField] private Transform[] waypoints;
    [SerializeField] private Transform player;
    [SerializeField] private float speed = 4f;
    [SerializeField] private float chaseRange = 4f;
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        // преследовать игрока, когда он рядом, или патрулировать маршрут
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Физика и игровой процесс