- Unreal Engine Pawn
- Pawn и Controller
- Передвижение объекта класса Pawn
- Настройки Details для Pawn (class Defaults)
- Override functions. Переопределение событий в Pawn
- Подклассы Pawn в Unreal Engine
- Default Pawn
- Spectator Pawn
- Character
- Практика в Unreal Engine: создание базового передвижения объекта класса Pawn. Функция Set Actor Location
- Объект класса Pawn
- Pawn и Player Controller
- Поворот камеры BP_Pawn
- Set Actor Location
- Базовое передвижение Pawn
- Скорость базового передвижения Pawn
Друзья, приветствую, с Вами Будуев Антон. В этой статье мы обсудим Blueprint-класс Pawn в Unreal Engine (UE4, UE5) или, как его еще называют по-русски, Павн, Пон или Пешка.
Вскоре выйдет моя бесплатная книга по Blueprints для Unreal Engine в PDF формате. Как она выйдет, рекомендую её скачать, чтобы Вы детально изучили блюпринты Анрил Энджин.
Unreal Engine Pawn
В Unreal Engine класс Pawn — это фундаментальный строительный блок для создания одушевлённых игровых объектов, которые могут управляться игроком или искусственным интеллектом (ИИ). Это базовый класс для всего, что ходит, бегает, прыгает, стреляет и так далее.
Pawn (пешка) — это подкласс Actor, который наделён дополнительным функционалом, связывающим объект Пешки с управляющим контроллером. Замечу, что Pawn не занимается самой логикой управления. Он просто предоставляет интерфейс для взаимодействия с другими частями движка и даёт возможность управлять одушевлённым объектом, то есть собой. Обычно логикой управления занимается контроллер. А основная цель Pawn — представлять собой контролируемое тело для контроллера.
В многопользовательских играх Pawn является реплицируемым объектом, то есть он копируется для всех клиентов. Но, реплицирование происходит именно самого объекта, а не свойств, которые Вы в нём определите. Пользовательские свойства и функционал нужно реплицировать отдельно вручную.
Pawn и Controller
Важно понимать, что по умолчанию абсолютно к любому объекту Pawn всегда подключен какой-либо из контроллеров — или Player Controller, или AI Controller. При чём между контроллерами и Пешками существует отношение один к одному, то есть каждый контроллер в любой момент времени управляет только одной Пешкой (однако, в некоторых ситуациях это можно изменить).
При создании объекта класса Pawn им уже владеет ИИ на основе базового класса AI Controller, встроенного в движок Анрил Энджин.
Естественно, так как он базовый, то управляющей логики там нет. Поэтому Вы с легкостью можете создать свой класс AI Controller, описав там свою логику управления объектом Пешки, и затем подключить этот класс вместо базового в настройках Pawn во вкладке Details, которые мы разберём чуть ниже.
Еще раз повторюсь, по умолчанию объектом Пешки всегда владеет базовый или пользовательский AI Controller. А далее, во время игры, это владение может перехватить текущий Player Controller при помощи функции Posses. Контроллер игрока будет владеть этой пешкой до тех пор, пока либо Пешка не будет удалена, либо противоположная функция UnPosses не отсоединит Player Controller от Pawn. После отсоединения, Пешкой вновь будет владеть AI Controller, прописанный в параметрах Details.
Также Player Controller может владеть конкретной Пешкой сразу после старта игры, если эта Пешка указана в качестве Default Pawn в настройках Game Mode запущенного игрового уровня.
Таким образом, любой Pawn всегда находится под управлением контроллера игрока или ИИ, если иное не назначено в настройках Details (в данных настройках можно полностью выключить автоматическое ИИ овладевание).
Передвижение объекта класса Pawn
Как я уже описывал ранее, основное предназначение класса Pawn в Unreal Engine (UE4, UE5) — это расширение класса Actor функционалом связки контроллера и объекта Pawn, чтобы контроллер мог управлять этим объектом, передавая входящие сигналы от игрока (Input) или ИИ. Другого специального функционала в Pawn нет. Поэтому, чтобы заставить передвигаться объект пешки от Input сигналов контроллера, необходимо вручную описать логику перемещения данного объекта.
В Blueprints добавить движение в объекты класса Pawn можно несколькими способами. Во-первых, можно использовать функцию Add Actor World Offset, которая задаёт смещение объекта на некоторое количество пунктов относительно своего прежнего положения. Также можно использовать функцию Set Actor Location, которая задаёт новые координаты для объекта. Настраивать данную функцию немного сложнее, чем предыдущую, так как нужно рассчитывать новые координаты. Пример создания движения для пешки с помощью SetActorLocation мы рассмотрим ниже в этой статье в разделе практики.
Также для базового передвижения Pawn можно использовать специальный Unreal Engine Component (компонент) Floating Pawn Movement, который внутри себя имеет настройки скорости, ускорения, торможения. Данный компонент мы разберём в отдельной статье.
Если же Вы хотите использовать более широкий функционал для создания реалистичного передвижения двуногого персонажа, который к тому же еще и автоматически реплицируется, то тогда нужно использовать не класс Pawn, а унаследованный от него подкласс Character. Именно в классе Character создателями игрового движка Unreal Engine заранее подготовлены к использованию компоненты для создания двуногого персонажа с капсульной коллизией. А также добавлен доступный только в этом классе специализированный компонент Character Movement для создания корректного физического передвижения двуногого персонажа.
Настройки Details для Pawn (class Defaults)
В меню Details содержатся как унаследованные параметры от класса Actor, так и настройки, характерные для разбираемого класса Пешки. Details для Actor мы уже разбирали в соответствующей статье про класс акторов. Сейчас же сконцентрируемся только на настройках Pawn.
- Use Controller Rotation Pitch (bool, по умолчанию False) — включить повтор наклона Пешки (Pitch) в соответствии с наклоном Player Controller (действует, если Пешкой владеет контроллер игрока).
- Use Controller Rotation Yaw (bool, по умолчанию False) — включить повтор поворота Пешки (Yaw) в соответствии с поворотом Player Controller (действует, если Пешкой владеет контроллер игрока).
- Use Controller Rotation Roll (bool, по умолчанию False) — включить повтор крена Пешки (Roll) в соответствии с креном Player Controller (действует, если Пешкой владеет контроллер игрока).
- Can Affect Navigation Generation (bool, по умолчанию False) — включить влияние объекта Pawn на генерацию навигационной сетки. Если False — влияние самого объекта на генерацию выключено, но компоненты этого объекта по-прежнему влияют на данную генерацию.
- Auto Possess Player — опция определяет какой Player Controller автоматически овладеет текущей Пешкой при старте её работы на игровом уровне. По умолчанию опция отключена (Disabled).
- Auto Possess AI — опция определяет время, когда AI Controller овладеет текущей Пешкой (если Auto Possess Player — Disabled). На выбор представлено 4 варианта:
— Disabled — автоовладевание полностью выключено;
— Placed in World — автоовладевание происходит только при ручном помещении Pawn в игровой мир в Unreal Editor;
— Spawned — автоовладевание происходит только при спавне Пешки через код во время игры;
— Placed in World or Spawned — автоовладевание происходит всегда, и при ручном размещении объекта, и при его спавне. - AI Controller Class — выбор класса AI Controller для управления Pawn ИИ.
- Override Input Component Class — выбор класса Input Component для переопределения базового Default Input Component Class.
Override functions. Переопределение событий в Pawn
В классе Pawn, в разделе Function / Override, находятся системные события Unreal Engine, которые можно переопределить. Иначе говоря, в этих событиях по умолчанию уже описана определённая системная логика, которую Вы, исходя из Ваших потребностей, можете изменить. В данном разделе перечислены события, унаследованные как от класса Actor, так и от класса Pawn. Переопределяемые события от класса Актор Вы можете изучить в отдельной статье: Events Actor. Здесь же обсудим только события, относящиеся к Pawn.
- Event Possessed
Событие Possessed вызывается при овладевании контроллером текущим Pawn. В многопользовательских играх вызов происходит только на сервере.
Выходящий параметр:
New Controller — ссылка на объект базового класса Controller, который начал владеть Пешкой.
- Event Unposessed
Событие Unposessed вызывается при окончании владения контроллером текущим Pawn. В многопользовательских играх вызов происходит только на сервере.
Выходящий параметр:
Old Controller — ссылка на объект базового класса Controller, который перестал владеть Пешкой.
- Event Receive Controller Changed
Событие Receive Controller Changed вызывается на сервере и клиенте-владельце после смены контроллера Пешки. Именно через данное событие мы имеем возможность на сетевых клиентах отследить у Пешки смену контроллера. Другие события, которые разобрали выше (Possessed и Unposessed) не позволяют этого сделать, так как они вызываются только на сервере.
Выходящие параметры:
Old Controller — ссылка на объект базового класса Controller, который перестал владеть Пешкой.
New Controller — ссылка на объект базового класса Controller, который начал владеть Пешкой.
- Event Receive Restarted
Событие Receive Restarted вызывается на сервере для всех Pawn и клиенте-владельце для всех Пешек игрока в момент перезапуска Pawn (обычно при изменении владения).
Подклассы Pawn в Unreal Engine
Default Pawn
В целом, подкласс Default Pawn мало чем отличается от базового родительского Pawn. Если базовый класс Пешки просто связывает создаваемый объект с управляющим контроллером, то подкласс Default Pawn содержит некоторые дополнительные компоненты и функции, предоставляя разработчику более удобный и подготовленный вариант управляемого контроллером объекта.
А именно, класс DefaultPawn в UE5 (UE4) содержит собственный компонент Movement Component, а также минимальную коллизию в виде сферического компонента Collision Component для реализации взаимодействия с физическим миром и компонент Static Mesh Component, чтобы можно было отобразить 3D-модель в игровом мире.
Но, если коллизию и Mesh разработчик может и сам добавить в класс Pawn, то вот компонент Movement Component — уже нет. Собственно, этим компонентом в основном и различается Default Pawn от базового класса Пешки.
Default Pawn Movement Component — это специализированный компонент для создания передвижения (полёта) без учёта гравитации, включающий в себя базовые настройки этого передвижения, такие как MaxSpeed, Acceleration, Deceleration и ряд других. Более подробно данный компонент мы рассмотрим в отдельной статье.
Spectator Pawn
Класс Spectator Pawn является подклассом Default Pawn. По-русски его еще называют «Пешка-Зритель». В целом, это тот же Default Pawn, с теми же компонентами коллизии и передвижения, но только без компонента Mesh.
Spectator Pawn идеально подходит для функций наблюдения со стороны. Например, если в игре нужно реализовать игрока без физической модели, чтоб игрок был просто камерой и, управляя ею, мог наблюдать за игровым уровнем.
Character
Character является подклассом Pawn с добавлением компонентов Character Movement Component, Capsule Component и Skeletal Mesh Component. Данный подкласс предназначен для вертикально-ориентированного представления игрока (в основном двуногого персонажа), который может ходить, бегать, прыгать, летать и плавать по миру. Этот класс также содержит реализации базовых сетевых моделей и моделей ввода.
Исходя из вышесказанного, класс Character является основным для создания человеческих персонажей. Более детально мы его рассмотрим в отдельной статье.
Практика в Unreal Engine: создание базового передвижения объекта класса Pawn. Функция Set Actor Location
Цель данной практики — воочию посмотреть, что объекты Pawn действительно привязываются к контроллеру, когда он начинает владеть ими, и получают управление от него (Input-сигналы от игрока). А также на примере разобрать принципы создания базового движения Pawn при помощи функции Set Actor Location, которая способна задавать новые координаты объекту.
Саму практику мы будем реализовывать в стандартном шаблоне проекта игры Unreal Engine (UE5) от первого лица.
Объект класса Pawn
- Через меню Blueprint class в Content Browser создадим Blueprint класса Pawn. Дадим ему имя BP_Pawn и разместим его на игровом уровне.
- Для визуализации данного объекта добавим ему Mesh в виде сферы. Для этого в разделе компонентов добавим компонент Sphere и перенесем этот компонент в корневой root-уровень, кликнув по компоненту Sphere левой клавишей мыши и не отпуская перенеся его на элемент DefaultSceneRoot. Эту операцию сделать нужно обязательно, чтобы коллизия компонента Sphere учитывалась, как коллизия всего Актора.
Pawn и Player Controller
- Перейдем во вкладку Event Graph и разместим в ней событие Key F, которое срабатывает по нажатию игроком клавиши F на клавиатуре. Чтобы проверить работу данного события, подсоединим к нему ноду Print String, которая должна будет вывести текст «Hello» при нажатии на F.
- Скомпилируем проект, перейдем на игровой уровень и запустим игру. Первое, что мы увидим, это то, что игра запустилась от стандартного персонажа данного шаблона игры от первого лица. Далее мы можем увидеть наш BP_Pawn, размещенный на уровне в виде сферы.
- Нажмём клавишу F и… ничего не произойдёт. Хотя BP_Pawn на сцене, и в этом блюпринте имеется код, выводящий строку «Hello», но при нажатии на F, — всё равно ничего не происходит.
Почему код не срабатывает? Всё просто. Дело в том, что за приём входящих данных от игрока (Input) отвечает Player Controller. А в текущий момент он владеет стандартным персонажем, а не нашим BP_Pawn. Соответственно, нажатие F в нашу Пешку не транслируется. Поэтому, чтобы исправить данную ситуацию, нужно Player Controller связать с нашим BP_Pawn, иначе говоря, чтобы он завладел нашей пешкой.
В данной практике мы их свяжем принудительно через свойства Details нашей Пешки. Для этого выделим наш объект, перейдём во вкладку Details в раздел Pawn и в параметре Auto Possess Player укажем Player 0. Так как в нашей демо-игре всего один игрок, то Player 0 и будет означать контроллер текущего игрока.
Запустим игру и… первое, что увидим, это игрок при старте игры перенесся из стандартного персонажа в наш BP_Pawn и смотрит на мир камерой по умолчанию, исходящей из центра нашей пешки. Далее нажмём F, и на экране отобразится текст «Hello».
Всё это стало возможным благодаря тому, что при старте игры контроллер игрока овладел нашим Pawn и стал передавать входящие сигналы игрока (Input с клавиатуры) в овладеваемую пешку, то есть в наш BP_Pawn.
Поворот камеры BP_Pawn
Теперь реализуем поворот камеры от поворота мыши. Для этого нужно описать поворот самого Player Controller при повороте мыши игрока. Писать этот код с нуля мы не будем, а просто возьмем его и скопируем из персонажа от первого лица данного шаблона игры.
- Перейдём в Content Browser по пути /All/Game/FirstPerson/Blueprints и откроем блюпринт BP_FirstPersonCharacter.
- Выделим блок кода Camera Input и скопируем его.
- Далее вставим этот код в наш BP_Pawn.
Данный код реагирует на событие поворота мыши и передаёт данные о повороте текущему контроллеру.
Теперь встроенная камера BP_Pawn будет также реагировать на поворот мыши, так как по умолчанию камера повторяет поворот контроллера.
Set Actor Location
Начнём реализовывать базовое передвижение объекта BP_Pawn при нажатии на клавишу F при помощи функции Set Actor Location. Данная функция задаёт новые координаты Актора на игровой сцене.
Чтобы реализовать при помощи этой функции передвижение, нужно к текущим координатам объекта добавить смещение в несколько пунктов. И получившиеся новые координаты отправить в Set Actor Location. Данную операцию нужно производить постоянно, в цикле. Таким образом, объект будет передвигаться на величину смещения.
Вопрос теперь в том, как рассчитать смещение. Для этого мы получим текущий поворот контроллера игрока, далее по этому повороту вычислим вектор направления вперед, что будет характеризовать направление контроллера игрока и камеры. Данный вектор и будет нашим смещением, которое мы будем добавлять к текущим координатам объекта BP_Pawn.
- Удалим функцию Print String, она нам больше не нужна.
- После события Key F вызовем функцию Set Actor Location.
- Далее нодой Get Control Rotation получим текущий поворот контролера игрока.
- Из этого поворота нодой Get Forward Vector вернём единичный вектор направления вперёд.
- Далее получим текущие координаты нашего BP_Pawn. Сделаем это нодой Get Actor Location.
- Теперь, на последнем шаге, вычислим новые координаты, куда функция Set Actor Location перенесет наш объект. Для этого к текущим координатам из пункта 5 добавим координаты вектора вперед из пункта 4. И весь результат направим в параметр New Location функции Set Actor Location.
Скриншот
Код на BlueprintUE
Таким образом, при каждом нажатии на F мы будем немного сдвигать наш объект в сторону поворота камеры (контроллера игрока). То есть получим некое подобие передвижения.
Базовое передвижение Pawn
Я думаю, Вы согласитесь, что передвигать объект, постоянно нажимая F, — это не вариант. То есть в качестве цикла для постоянного запуска Set Actor Location должно выступать что-то другое, а вот F просто должна включать этот цикл и выключать.
Предлагаю в качестве цикла использовать событие Event Tick. Данное событие срабатывает каждый такт обновления экрана игры. С одной стороны, событие достаточно простое, с другой стороны, его нужно использовать с особой осторожностью, чтобы не загрузить систему тяжёлым кодом при каждом обновлении экрана. Более подробно об этом событии и тонкостях работы с ним Вы можете узнать в отдельной статье: Unreal Engine Event Tick.
- Вызовем событие Event Tick.
- Напрямую Set Actor Location к Event Tick мы подключать не будем, так как тогда движение будет постоянным, не реагирующим на нажатие / отжатие F. Чтобы всё это связать воедино, используем ноду Gate, которая действует как некие ворота, пропускающие и не пропускающие сигнал.
- Итак, в параметр Enter ноды Gate подадим поток от Event Tick. Так как у Gate параметр Start Closed по умолчанию True, то это означает, что изначально ворота закрыты, и сигнал Enter далее не проходит. Чтобы открыть ворота, подадим сигнал Pressed от события F в параметр Open от ноды Gate. И, соответственно, для закрытия ворот — Released в Close. Таким образом, при нажатии на F мы будем открывать ворота и пропускать сигнал от Event Tick далее, а при отжатии F ворота будут закрываться, блокируя сигнал тика. Осталось только поток Exit ноды Gate переправить во входящий поток Set Actor Location.
- Если Вы запустите сейчас игру, то увидите, что наш Pawn передвигается с небольшой скоростью, но при этом не учитывает пересечения с другими объектами, просто перемещаясь сквозь них. Чтобы это исправить, нужно всего лишь у функции Set Actor Location в параметре Sweep поставить True. Таким образом, данная функция будет не просто перемещать объект на новые координаты, но и учитывать его столкновение с другими объектами игрового мира. Причём все эти столкновения можно обрабатывать, так как на выходе функции имеется выходной параметр Sweep Hit Result, который раскрывается на большую структуру Break Hit Result, содержащую подробную информацию о столкновении.
Скриншот
Код на BlueprintUE
Обратите внимание, что в таком случае, если будет происходить столкновение, например тогда, когда Вы направите камеру вниз, к полу, то объект будет останавливаться. Чтобы движение возобновилось, необходимо камеру повернуть в другое направление.
Скорость базового передвижения Pawn
В нашей практике осталось настроить последний момент — регулируемая скорость передвижения Pawn. В текущей версии у нас движение создаётся добавочными пунктами из вектора с направлением вперед, которые мы добавляем к текущим координатам на каждом кадре игры. Чтобы увеличить скорость, нужно увеличить эти добавочные пункты. Также, для того чтобы скорость движения объекта была на всех ПК одинаковая, при её расчёте необходимо учесть параметр Delta Seconds из события Event Tick. Что это такое и почему Delta Seconds нужно учитывать, Вы можете прочитать в отдельной статье: Unreal Engine Delta Seconds.
- В BP_Pawn введём переменную скорости Speed типа float. Зададим ей начальное значение в 200.
- Для того чтобы скорость была одинаковая на всех ПК, умножим Speed на Delta Seconds из события Event Tick.
- Получившийся результат умножения еще раз помножим на значения вектора вперед и далее этот результат сложим с текущими координатами Актора. Всё это и будет являться новыми координатами для Set Actor Location, учитывающими значения скорости и Delta Seconds.
Скриншот
Код на BlueprintUE
Совет. Вскоре выйдет моя бесплатная книга по Blueprints для Unreal Engine в PDF формате. Как она выйдет, рекомендую её скачать, чтобы Вы детально изучили блюпринты Анрил Энджин.