ИИ для машин быстро и просто
Салют DTF! Надеюсь, ты с пользой проводишь карантин и разрабатываешь новые игры? Мой туториал об ИИ для машин в Unreal Engine может помочь.
Из коробки в UE4 ИИ доступен только для персонажей. Всё остальное нужно делать самому. В том числе машины. Об этом и будет туториал.
Заготовка
Пусть наш учебный проект будет самым простым. Поэтому используем Advanced Vehicle C++ Template шаблон.
1. Player Pawn
Начнем с Player Pawn. Это не обязательный шаг, просто мне нравится вид сверху — оттуда все хорошо видно. Создадим blueprint на основе класса Pawn и определим его следующим образом:
Добавим SpringArm компонент и Camera component. Настройте их так, как вам нравится. Мой вариант:
Добавим также FloatingPawnMovement компонент, иначе камера не будет двигаться.
С уровня удалим все PlayerStart объекты и на машине уберем галочку со свойства AutoPossesPlayer. А на объекте нового типа BP_Player, это свойство выставим в значение Player 0. Теперь при запуске игры мы сможем управлять камерой при помощи WASD. А мышкой дальше будем пользоваться чтобы давать команду машине.
2. Настройка ИИ
Теперь ИИ. Нам нужен AIController:
И Blackboard с одной переменной ClickLocation типа Vector. И, наконец, Behavior Tree:
В Behavior Tree только одна команда Move To с параметром ClickLocation, который мы определили и проинициализировали раньше.
Последний обязательный пункт: добавим NavMeshBoundsVolume на уровень, иначе PathFollowingComponent не будет работать.
Чтобы не тратить время, я пока не вдавался в детали. Но если что-то непонятно — пишите в комментариях.
Если бы мы делали ИИ для персонажей, то он бы уже заработал. Но с машинами все сложнее.
ИИ машины
Разберемся как работает Move To команда в UE4.
Когда Behavior Tree запускает команду Move To, оно на самом деле выполняет метод AAIController::MoveTo. Затем управление переходит в модуль AIModule, который в итоге вызывает метод UNavMovemementComponent::RequestDirectMove.
Только UCharacterMovementComponent реализует этот метод. Поэтому настроить ИИ для персонажей так просто в UE4. Для всего остального разработчикам придется потрудиться самим.
Сигнатура метода выглядит так:
Параметр MoveVelocity — это вектор скорости, направленный в сторону цели. Если умножить скорость на DeltaTimeSeconds, то мы получим вектор расстояния до цели. И с ним работать уже намного проще.
Путь до цели состоит из сегментов. И если мы движемся не по последнему, то bForceMaxSpeed равен true. AIModule как бы говорит нам: «Гони по максимуму, до цели еще далеко!».
Итак, сделаем свой movement компонент c именем UAIVehicleMovement. Отнаследуем его от UWheeledVehicleMovementComponent4W и переопределим RequestDirectMove метод:
И изменим конструктор класса машины так, чтобы он использовал новый movement компонент:
Запустим игру. Если вы выполнили все шаги правильно, то после клика мышкой на карте, мы увидим сферу на месте клика и красную линию — дистанцию от машины до клика.
ПИД-регулятор
По идее на этом можно было бы закончить статью. Дальше уже идет чистое программирование :)
Есть, наверно, много способов реализовать движение машины из точки А в точку Б. Я использовал ПИД-регуляторы. Я не смогу понятно объяснить, как они работают. Там много математики и куча вещей, которые я сам не понимаю до конца. Но вот эта хорошая статья мне здорово помогла:
Я прочитал статью, покопался в интернете и реализовал свой ПИД-регулятор вот таким образом:
Если по коду что-то непонятно — задавайте вопросы.
Вот так все выглядит в действии:
p.s. Эта статья — перевод. Оригинал я написал в своем блоге на английском языке: https://superyateam.com/2020/04/18/how-to-implement-vehicle-ai-in-ue4. Подписывайтесь, раз в месяц я пишу статьи про геймдев и UE4.