{"id":2412,"title":"\u0423\u0433\u0430\u0434\u0430\u0439\u0442\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 \u043f\u043e \u0437\u0432\u0443\u043a\u0443 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u043f\u0438\u0432\u0430 \u0438 \u043f\u0435\u043d\u0438\u044e \u043a\u0438\u0442\u043e\u0432","url":"\/redirect?component=advertising&id=2412&url=https:\/\/vc.ru\/special\/sound&placeBit=1&hash=1620c155cf544062859cfaabcc12f9dd73613708c43c381ba3dbf0828037edcd","isPaidAndBannersEnabled":false}
Unreal Engine
Superyateam

ИИ для машин быстро и просто

Салют DTF! Надеюсь, ты с пользой проводишь карантин и разрабатываешь новые игры? Мой туториал об ИИ для машин в Unreal Engine может помочь.

Из коробки в UE4 ИИ доступен только для персонажей. Всё остальное нужно делать самому. В том числе машины. Об этом и будет туториал.

Заготовка

Пусть наш учебный проект будет самым простым. Поэтому используем Advanced Vehicle C++ Template шаблон.

1. Player Pawn

Начнем с Player Pawn. Это не обязательный шаг, просто мне нравится вид сверху — оттуда все хорошо видно. Создадим blueprint на основе класса Pawn и определим его следующим образом:

​BP_Player blueprint

Добавим SpringArm компонент и Camera component. Настройте их так, как вам нравится. Мой вариант:

Добавим также FloatingPawnMovement компонент, иначе камера не будет двигаться.

С уровня удалим все PlayerStart объекты и на машине уберем галочку со свойства AutoPossesPlayer. А на объекте нового типа BP_Player, это свойство выставим в значение Player 0. Теперь при запуске игры мы сможем управлять камерой при помощи WASD. А мышкой дальше будем пользоваться чтобы давать команду машине.

2. Настройка ИИ

Теперь ИИ. Нам нужен AIController:

Не пинайте за Cast в обработчике Event Tick ​

И 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. Для всего остального разработчикам придется потрудиться самим.

Сигнатура метода выглядит так:

void RequestDirectMove(const FVector& MoveVelocity, bool bForceMaxSpeed)

Параметр MoveVelocity — это вектор скорости, направленный в сторону цели. Если умножить скорость на DeltaTimeSeconds, то мы получим вектор расстояния до цели. И с ним работать уже намного проще.

Путь до цели состоит из сегментов. И если мы движемся не по последнему, то bForceMaxSpeed равен true. AIModule как бы говорит нам: «Гони по максимуму, до цели еще далеко!».

Итак, сделаем свой movement компонент c именем UAIVehicleMovement. Отнаследуем его от UWheeledVehicleMovementComponent4W и переопределим RequestDirectMove метод:

Super::RequestDirectMove(MoveVelocity, bForceMaxSpeed); FVector VehicleLocation = GetOwner()->GetActorLocation(); FVector Destination = VehicleLocation + MoveVelocity * GetWorld()->GetDeltaSeconds(); DrawDebugLine(GetWorld(), GetOwner()->GetActorLocation(), Destination, FColor::Red, false, 1.f, 0, 3.f);

И изменим конструктор класса машины так, чтобы он использовал новый movement компонент:

// declaration: AVehicleAIPawn(const FObjectInitializer& ObjectInitializer); // definition: AVehicleAIPawn::AVehicleAIPawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer.SetDefaultSubobjectClass<UAIVehicleMovement>(AWheeledVehicle::VehicleMovementComponentName))

Запустим игру. Если вы выполнили все шаги правильно, то после клика мышкой на карте, мы увидим сферу на месте клика и красную линию — дистанцию от машины до клика.

ПИД-регулятор

По идее на этом можно было бы закончить статью. Дальше уже идет чистое программирование :)

Есть, наверно, много способов реализовать движение машины из точки А в точку Б. Я использовал ПИД-регуляторы. Я не смогу понятно объяснить, как они работают. Там много математики и куча вещей, которые я сам не понимаю до конца. Но вот эта хорошая статья мне здорово помогла:

Я прочитал статью, покопался в интернете и реализовал свой ПИД-регулятор вот таким образом:

Если по коду что-то непонятно — задавайте вопросы.

Вот так все выглядит в действии:

p.s. Эта статья — перевод. Оригинал я написал в своем блоге на английском языке: https://superyateam.com/2020/04/18/how-to-implement-vehicle-ai-in-ue4. Подписывайтесь, раз в месяц я пишу статьи про геймдев и UE4.

{ "author_name": "Superyateam", "author_type": "self", "tags": [], "comments": 5, "likes": 23, "favorites": 54, "is_advertisement": false, "subsite_label": "unrealengine", "id": 126291, "is_wide": true, "is_ugc": true, "date": "Sun, 19 Apr 2020 09:56:23 +0300", "is_special": false }
0
5 комментариев
Популярные
По порядку

Неужели cast такой прожорливый, что за него нужно извиняться?

0

Вроде да. Плюс это можно сделать один раз, в begin play например. И не кастить потом каждый тик

0

Это да, просто интересно насколько дела плохи с кастом

0

Насколько, сказать не могу. Просто очень часто встречаю предостережения об использовании каста в тик функции. 

1

SteeringInput скрывает член класса, а при замене названия, блупринты теряют физику, и меши машин просто вращаются вокруг точки Actor'а. Есть решение?

0
Читать все 5 комментариев
null