UE 5.0. Система навигации.
Перевод и разбор урока https://docs.unrealengine.com/5.0/en-US/modifying-the-navigation-mesh-preparation-guide-in-unreal-engine/ . Система навигации пешек на уровне, позволяет пешке двигаться к определенным координатам, обходя препятствия (и другие пешки).
Для начала создаем проект, лучше взять готовый шаблон: Third Person или Top Down, без разницы. Присваиваем имя проекта и создаем. Я пробовал оба шаблона, далее буду отталкиваться от шаблона Top Down.
Создаем новый уровень через меню File->New Level… Выбираем уровень Basic.
Плоскость уровня заливаем любым материалом. Я в папке проекта Materials сделал копию материала, после чего присвоил ему другой Base Color. Для этого берем через ЛКМ существующий материал, тянем в свободное место, отпускаем и выбираем Copy. Такая операция возможна над любыми сущностями движка. После подготовки материала, перетаскиваем его на модель плоскости.
Да, важно сохранить уровень File->Save Level, выбрать путь Content/TopDown/Maps - чтобы уровни у нас лежали в одном месте.
После чего можно начинать заполнять наш уровень, чтобы получить примерно следующее:
Объекты взяты из проекта Content/LevelPrototyping/Meches. Можно скопировать готовые объекты и подогнать под свой вкус по материалам.
Обратим внимание на красные сферы, это целевые объекты для перемещения пешки. Т.е. пешка будет бегать между этими сферами. В проекте может отсутствовать модель сферы, но это не страшно. Добавим из примитивов.
Кнопка с плюсиком позволяет добавлять объекты в проект. Сделаем для сферы отдельный материал с красным цветом и поместим материал на сферу. Именно поместим, через Content Drawer выберем материал и мышкой перетащим на сферу на сцене - готово. Последний штрих, убираем коллизию у сферы.
Выбираем сферу, находим в панели Details свойство Collision Presets и устанавливаем значение NoCollision. Это важно! Пешки могут заходить внутрь сферы. Иначе, будут тупить и не всегда прибегать к сферам, чуть позже станет понятно почему.
Когда все настройки сферы выполнены, то можно ее скопировать и расставить по уровню.
Переходим к главной части, настройка пешки.
Берем готовую пешку Content/TopDown/Blueprints/BP_TopDown_Character и копируем, можно и в этой папке оставить, можно перенести в другую. Я создал отдельную папку NavSystem и скопировал пешку туда. Переименовываем пешку в BP_NPC_Character.
Что хорошо - пешка уже настроена. Модель, материал, анимации - все уже готово и можно использовать.
Чего нет? Нет поведения пешки, что сейчас мы и будем прописывать.
Необходимо реализовать следующий алгоритм:
- у пешки есть какой-то список координат куда необходимо прибежать;
- нужно выбрать координату (одну сферу), допустим случайно;
- прибежать;
- повторить выбор координат и т.д.
Добавляем переменные в пешку, для этого открываем пешку по двойному клику. Смотрим левую панель.
Три переменных и важно тут ничего не напутать.
<Targets> - массив Actor - это красные сферы на сцене. Actor это универсальный класс для всех участников сцены.
<CurrentTarget> - выбранный Actor, к которому собираемся двигаться.
<RandomLocation> - случайно выбранные координаты около объекта, пока не суть, ясно станет чуть позже.
Targets настраиваем следующим образом:
Флажок Instance Editable добавляет переменную для правки в панель Details пешки. А это нам как раз нужно. Остальные переменные проще и расписывать их не буду.
Рисуем чертеж (blueprint) или собираем…
Это вся программа. Узлы программы зовутся нодами. Более детально как составлять программу есть в уроке (ссылка в начале статьи). В данном случае описаны два события (event) - MoveNPC и BeginPlay.
Детально разберем, что это и зачем.
MoveNPC - выбирает цель для пешки и перемещает ее по координатам цели:
- custom event - заголовок события (функции), далее ведем пальцем по белой линии (pin EXEC, очередь выполнения программы);
- Set CurrentTarget присваиваем некое значение в переменную CurrentTarget, смотрим откуда получим данные:
- берем значения переменной Targets (несколько значений, красные сферы);
- LAST INDEX вернет максимальный индекс массива (номер последнего элемента, первый элемент нуль);
- Random Integer in Range - выдаст случайный номер из диапазона от нуля до номера последнего элемента массива;
- GET - получим объект значение из массива по его номеру;
- Set CurrentTarget, с этого момента в переменной CurrentTarget лежит объект, к которому побежит пешка.
- Is Valid проверит, что в итоге мы получили что-то “живое”, это обработка ошибки, используем pin Is Valid - это успешное выполнение этой проверки, ошибочное значение обрабатывать не будем, т.е. выполнении функции MoveNPC прерывается и пешка будет просто стоять на месте;
- Set RandomLocation - получаем координаты выбранного объекта (сферы):
- берем CurrentTarget и узнаем координаты модели (Get Actor Location), координаты это вектор - три значения X, Y, Z;
- сложно читаемая функция GetRandomReachablePointInRadius вернет случайные координаты около выбранного объекта в радиусе 100. Обращаем внимание, что координаты это вектор - три значения X, Y, Z;
- для чего читаем CurrentTarget, а не тянем из предыдущих нодов? Из-за ноды Is Valid, до проверки мы не знаем можно ли пользоваться значением CurrentTarget. Поэтому только после проверки его безопасно читать и использовать.
- AI MoveTo - магия данной программы, которая отправит нашу пешку к указанным координатам. Отдельно стоит указать какую пешку мы перемещаем (pin Pawn). И указать Self, именно ту пешку, в которой пишем программу;
- В результате пешка или дойдет до цели (On Success) или не сможет дойти (On Fail);
- Delay - задержка пешки, пусть отдохнет. Параметр в секундах. В случае ошибки поиска (On Fail) отдыхать некогда;
- MoveNPC - запускаем функцию с начала, выбираем новую цель, идем, отдыхаем и т.д.
BeginPlay - выполняется один раз при старте и запускает событие MoveNPC.
Сохраняем и компилируем blueprint, это избавит нас от очевидных ошибок при выполнении. Переходим в редактор. Помещаем пешку на сцену, перетаскиваем из Content Drawer. Убеждаемся дополнительно, что пешка именно та.
При сложностях составить программу, следует более гибко подходить к редактору. Он готов упростить работу пользователю насколько это возможно. Если работа идет с переменной, можно мышкой схватить переменную и бросить на чертеж, после чего выбрать действие с переменной. Иногда, имеет смысл вытягивать результат из соседнего нода, чтобы получить сокращенный перечень возможных нодов (согласно типа значения). Экспериментируйте и не бойтесь.
Выбираем пешку на сцене и в панели Details ищем наш массив Targets. Заполняем:
Тут возможны несколько неприятностей:
- нет такого пункта, возвращаемся к настройкам пешки (двойной клик по пешке в Content Drawer), смотрим настройку переменной Targets, особенно флаг Instance Editable;
- не можем выбрать из списка сферы, возвращаемся к настройкам переменной и правим ее тип. Это должен быть массив объектов Actor.
Стоит объяснить как работает Is Valid и в каком случае он будет срабатывать с ошибкой. Допустим, заполнили 0-3 элемент, а 4 указать забыли, добавили, но не заполнили. В этом случае программа навигации остановится и пешка будет стоять на месте, без всяких ошибочных сообщений от движка при выполнении.
Навигация, добрались до темы статьи. Пришло время творить магию.
Добавляем объект навигации. Через волшебную кнопку с плюсиком (сферу добавляли через нее), выбираем панель актеров.
Выбираем NavMechBoundsVolume, это как раз тот самый объект, который будет отвечать за поиск пути. Получаем кубик на сцене, растягиваем его на всю поверхность сцены. Важно, чтобы он не висел над сценой, а был углублен в поверхность. После чего нажимаем кнопку “P” и видим магию.
Если магии нет, нужно сохранить проект, закрыть редактор и запустить его снова. Объект NavMechBoundsVolume разрисовал уровень по критериям проходимости для пешки. Обратите внимание, что под красными сферами нет блока проходимости. Это из-за отключенной коллизии. Так и должно быть.
Все готово, можно запускать и смотреть мультик.
В дополнение, хорошо было бы нашей автоматической и умной пешке добавить свой скин, это можно сделать правкой материала. Делаем копию существующего и правим копию.
Стоит поднять камеру чуть выше, надо найти плечо с камерой у игрового персонажа (которым игрок управляет) и увеличить длину плеча с 1400 до 3000-3500.
Что стоит добавить умную пешку на первый уровень? Надо:
- добавить сферы-цели (скопировав одну сферу и размножив на уровне);
- поставить пешку на уровень;
- заполнить массив целей для пешки.
- и все!
На стартовом уровне уже присутствует объект навигации, вся магия в наличии.
Здесь должна быть гифка, но не срослось.
- создание проекта из шаблона;
- добавление уровня;
- добавление моделей на уровень с правкой материалов;
- создание пешки из базовой, добавление переменных, создание чертежа;
- использование объекта NavMechBoundsVolume.