Во многих играх есть NPC, которые автоматически патрулируют игровую зону. Для реализации этого поведения можно использовать навигационную систему, но она немного более сложная, чем стандартный поиск пути — простое использование кратчайшего пути между двумя точками делает маршрут патрулирования ограниченным и предсказуемым. Вы можете получить более убедительную схему патрулирования, сохранив набор ключевых точек, которые «полезны» для прохождения NPC, и посещая их в определенной последовательности. Например, в лабиринте вы можете разместить ключевые точки патрулирования на перекрестках и углах, чтобы агент проверял каждый коридор. Для офисного здания ключевыми точками могут быть отдельные офисы и другие помещения.
Идеальная последовательность точек патрулирования будет зависеть от того, как вы хотите, чтобы NPC вели себя. Например, робот, вероятно, будет просто посещать точки в методическом порядке, в то время как человек-охранник может попытаться поймать игрока, используя более случайный шаблон. Простое поведение робота можно реализовать с помощью кода, показанного ниже.
Точки патрулирования передаются сценарию с помощью общедоступного массива преобразований. Этот массив можно назначить из инспектораокна Unity, в котором отображается информация о текущем выбранном игровом объекте, активе или настройках проекта, что позволяет вам для проверки и редактирования значений. Дополнительная информация
См. в Словарь с помощью GameObjectsОсновной объект в сценах Unity, который может представлять персонажей, реквизит, декорации, камеры, путевые точки и многое другое. Функциональность GameObject определяется прикрепленными к нему компонентами. Подробнее
См. в Словарь, чтобы отметить позиции точек. Функция GotoNextPoint устанавливает точку назначения для агента (которая также запускает его движение), а затем выбирает новую точку назначения, которая будет использоваться при следующем вызове. В нынешнем виде код перебирает точки в той последовательности, в которой они встречаются в массиве, но вы можете легко изменить это, скажем, с помощью Random.Range. для случайного выбора индекса массива.
В функции Update скрипт проверяет, насколько близко агент находится к месту назначения, используя remainingDistance. свойство. Когда это расстояние очень мало, выполняется вызов GotoNextPoint, чтобы начать следующий этап патрулирования.
// Patrol.cs
using UnityEngine;
using UnityEngine.AI;
using System.Collections;
public class Patrol : MonoBehaviour {
public Transform[] points;
private int destPoint = 0;
private NavMeshAgent agent;
void Start () {
agent = GetComponent();
// Disabling auto-braking allows for continuous movement
// between points (ie, the agent doesn't slow down as it
// approaches a destination point).
agent.autoBraking = false;
GotoNextPoint();
}
void GotoNextPoint() {
// Returns if no points have been set up
if (points.Length == 0)
return;
// Set the agent to go to the currently selected destination.
agent.destination = points[destPoint].position;
// Choose the next point in the array as the destination,
// cycling to the start if necessary.
destPoint = (destPoint + 1) % points.Length;
}
void Update () {
// Choose the next destination point when the agent gets
// close to the current one.
if (!agent.pathPending && agent.remainingDistance < 0.5f)
GotoNextPoint();
}
}
// Patrol.js
var points: Transform[];
var destPoint: int = 0;
var agent: NavMeshAgent;
function Start() {
agent = GetComponent.();
// Disabling auto-braking allows for continuous movement
// between points (ie, the agent doesn't slow down as it
// approaches a destination point).
agent.autoBraking = false;
GotoNextPoint();
}
function GotoNextPoint() {
// Returns if no points have been set up
if (points.Length == 0)
return;
// Set the agent to go to the currently selected destination.
agent.destination = points[destPoint].position;
// Choose the next point in the array as the destination,
// cycling to the start if necessary.
destPoint = (destPoint + 1) % points.Length;
}
function Update() {
// Choose the next destination point when the agent gets
// close to the current one.
if (!agent.pathPending && agent.remainingDistance < 0.5f)
GotoNextPoint();
}