Menu
CoddyTech

Погоня в радиусе

Часть раздела Физика и игровой процесс путешествия по 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 запоминает, преследует ли враг игрока, а между двумя радиусами его значение не меняется, поэтому враг продолжает делать то, чем занимался.

challenge icon

Задание

Средне

Сделай так, чтобы волк замечал игрока вблизи и сдавался, когда тот далеко.

  1. В FixedUpdate() вычисли горизонтальное расстояние до игрока: если оно меньше noticeRange, установи поле bool chasing в значение true; если больше giveUpRange — в false.
  2. Пока chasing равно true, направляй rb.linearVelocity к игроку со скоростью speed, сохраняя значение по оси y.
  3. В противном случае установи 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()
    {
        // заметить игрока, прекратить преследование и двигаться за ним или стоять на месте
    }
}

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

Потренируйтесь самостоятельно: Песочница Unity