- Unreal Engine controller
- Player Controller Unreal Engine (UE4, UE5)
- Настройки Details для PlayerController (class Defaults)
- Inherited variables. Унаследованные переменные в PlayerController
- Как создать и подключить контроллер игрока в Анрил Энджин
- Как получить Player Controller персонажа в UE5. Функция Get Player Controller
- Override functions. Переопределение событий в Player Controller
- Функции Possess и Un Possess
- Практика в Unreal Engine №1. Смена персонажа у PlayerController через Blueprint
- Практика в Unreal Engine №2. Переопределение событий «On Possess» и «On UnPossess» в классе PlayerController
- Практика в Unreal Engine №3. Ограничиваем Pitch камеры у игрока. Player Camera Manager
Друзья, приветствую, с Вами Будуев Антон. В данной статье мы поговорим о загадочном контроллере игрока в движке Unreal Engine (UE4, UE5): Player Controller.
Обсудим, для чего предназначен данный класс, его настройки, поговорим, как он используется в сетевых играх. Также рассмотрим события, которые можно переопределить в этом классе. И, наконец, займёмся практическим применением контроллера игрока в Анрил Энджин, а именно: научимся менять персонажа через Blueprint с помощью PlayerController и при этом выводить / удалять виджеты на экран игрока, а также ограничивать Pitch его камеры.
В целом же, в данной статье на практике мы будем работать со следующими функциями и событиями, которые так или иначе связаны с PlayerController в Unreal Engine: «Get Player Controller», «Possess» / «Un Possess», «Event On Possess» / «Event On Un Possess», «Player Camera Manager», «Set View Pitch» и другими вспомогательными функциями.
Unreal Engine controller
Итак, что же это такое? Unreal Engine controller — это субъект, не представленный «визуально-физически» в игровом мире, но, в то же время, присутствующий там и управляющий игровыми объектами класса Pawn. Или другими дочерними от него классами, например, Character.
Управление объектом возможно только после того, как Controller «овладеет» им либо с помощью специальной Blueprint-функции «Possess», либо же через настройки класса GameMode, либо же через специальные настройки класса самого объекта. Это управление будет продолжаться до тех пор, пока для текущего контроллера не сработает обратная функция «Un Possess» (отказ от управления). Либо же пока он не «овладеет» каким-то другим объектом игрового мира.
Controller получает уведомления от движка Анрил Энджин о различных событиях, происходящих в игре с Pawn (Character), которыми он управляет. Это позволяет ему реагировать на эти события, перехватывая их и заменяя стандартное поведение управляемого персонажа на другое, заранее определенное разработчиками игры.
По умолчанию у Controller в Unreal Engine может быть только один управляемый персонаж. Это значит, что в каждый момент времени он владеет одним конкретным объектом. Кстати, данное ограничение можно обойти. Но все же создатели игрового движка не рекомендуют это делать и менять их концепцию. Эта же концепция относится и к объекту. В конкретный момент времени у него может быть только один контроллер.
В UE5 (UE4) применяются два типа Blueprint класса управляющих менеджеров: Player Controller (контроллер игрока) и AI Controller (контроллер искусственного интеллекта). Оба эти класса являются дочерними от базового Controller, который, в свою очередь унаследован от Actor.
Контроллер ИИ мы рассмотрим в следующей статье про AI Controller. А сейчас же давайте разберём контроллер игрока.
Player Controller Unreal Engine (UE4, UE5)
Blueprint class PlayerController — это класс-менеджер в Unreal Engine, который обрабатывает ввод данных (Input Action) с клавиатуры, мышки, джойстика от человека-игрока. И на основе этих данных управляет передвижением и поведением персонажа (аватара этого игрока) в игровом мире. Это своеобразный интерфейс между Pawn (Character) и игроком, управляющим этим объектом. По сути, он представляет волю игрока-человека.
При настройке класса PlayerController в блюпринтах следует учитывать, какую функциональность Вы разместите в нем, и какую в классе Pawn (Character).
Идея создателей движка Unreal Engine заключается в том, что Pawn и Player Controller должны работать вместе, дополняя друг друга. Они оба представляют игрока в игре. Pawn — это физический образ персонажа в игровом мире, а Player Controller — его воля. Поэтому, обычно в персонаже (Pawn) описываются его свойства, 3D-модель и анимации, а в контроллере обрабатывается ввод данных (Input Action).
Но несмотря на это, управление персонажем (ввод данных) также можно реализовать и в классе Pawn. Возникает вопрос: зачем тогда нужен PlayerController?
Дело в том, что в игровом мире объекты классов Pawn и Character могут меняться. Например, сначала игрок управляет персонажем (класс Character), который является главным героем. Затем персонаж садится в машину, и игрок начинает управлять объектом класса Pawn — машиной. После этого игрок может переключиться на управление другим персонажем, например, другом того, кто сел в машину. Этот персонаж также будет относиться к классу Character, но уже другому, для второго персонажа.
В подобных ситуациях, если логику управления персонажами описать в классе Pawn, а не в классе управляющего менеджера, то её придётся дублировать во всех объектах, за которых играет игрок. Это не только неудобно, но и неправильно с точки зрения организации кода.
На помощь приходит класс PlayerController в Unreal Engine. Если описать всю логику управления персонажами именно в нём, то не придётся повторять код в разных классах. Когда игрок меняет своего игрового персонажа, нужно лишь переназначить управление у контроллера на другие объекты с помощью Blueprint-функций «Possess» и «Un Possess».
Чтобы в Unreal Engine у контроллера произвести смену управляемого персонажа через Blueprint, используйте в Event Graph этого контроллера ноду «Possess» (овладеть). Во входном параметре которой («In Pawn») присоедините ссылку на новый объект персонажа. Данный процесс мы будем разбирать на практике в данной статье в разделе ниже.
Также нужно знать, что Player Controller — это один из основных компонентов сетевого взаимодействия в многопользовательских играх движка Unreal Engine. Когда в игре участвуют несколько игроков, на сервере создаётся отдельный экземпляр контроллера для каждого из них. При этом каждый сетевой клиент получает свой собственный игровой контроллер, который предназначен только для него.
Иными словами, у каждого клиента имеется свой собственный Player Controller, который существует исключительно на его стороне и на сервере. При этом клиент не имеет доступа к Player Controllers других клиентов.
Настройки Details для PlayerController (class Defaults)
В меню Details содержатся как унаследованные параметры от класса Actor, так и настройки, характерные для разбираемого класса. Параметры для Actor мы уже разбирали в соответствующей статье про класс акторов. Сейчас же сконцентрируемся только на настройках PlayerController.
Player Controller:
- Player Camera Manager Class (по умолчанию значение None, при этом используется стандартный класс Engine.PlayerCameraManager). Определяет, какой класс CameraManager будет создан при инициализации Player Controller. Позволяет выбрать свой пользовательский класс Player Camera.
- Auto Manage Active Camera Target (bool, по умолчанию = True). Автоматический выбор цели для активной камеры. True — разрешить контроллеру управлять целью камеры (обычно это подконтрольный Pawn). False — ручной пользовательский выбор цели для камеры.
- Smooth Target View Rotation Speed (float, по умолчанию = 20). Скорость интерполяции смешивания поворота Target View для более плавного обновления клиента. Target View — Актор, через который PlayerController смотрит на мир.
- Should Perform Full Tick when Paused (bool, по умолчанию = False). Исполнять ли функцию Tick полностью, когда игра поставлена на паузу.
Cheat Manager:
- Cheat Class (по умолчанию используется стандартный класс CheatManager). Позволяет выбрать свой пользовательский класс менеджера читов. Cheat Manager выполняет тестирование и отладку кода в Unreal Engine, а также другие необходимые действия, не включаемые в итоговую сборку игры.
Mouse Interface:
- Show Mouse Cursor (bool, по умолчанию = False). Отображать курсор мыши или нет.
- Enable Click Events (bool, по умолчанию = False). Включить события нажатия мыши по актору/компоненту.
- Enable Touch Events (bool, по умолчанию = True). Включить события сенсорного касания по актору/компоненту.
- Enable Mouse Over Events (bool, по умолчанию = False). Включить события наведения курсора мыши на актор/компонент.
- Enable Touch Over Events (bool, по умолчанию = False). Включить события сенсорного наведения пальца на актор/компонент.
- Click Event Keys (по умолчанию неактивный, активируется при Enable Click Events = True). Список клавиш для обработки события (по умолчанию левая кнопка мыши).
- Default Mouse Cursor (по умолчанию Default). Тип курсора мыши.
- Default Click Trace Channel (по умолчанию Visibility). Канал трассировки по умолчанию, используемый для определения нажатого объекта. Для выбора предлагаются стандартные каналы трассировки (World Static, World Dynamic, Pawn, Visibility, Camera, Physics Body, Vehicle, Destructible).
- Trace Distance (float, по умолчанию = 100000). Расстояние для трассировки при вычислении событий нажатия.
Game / Feedback:
- Force Feedback Enabled (bool, по умолчанию = True). Включить принудительную обратную связь.
Controller / Transform:
- Attach to Pawn (bool, по умолчанию = False). Прикрепить Player Controller к Pawn. True — местоположение контроллера будет соответствовать местоположению подконтрольного ему Pawn. False — местоположение обновляться не будет. При этом, в любом случае, вращение (rotation) будет соответствовать значениям настроек Control Rotation.
Inherited variables. Унаследованные переменные в PlayerController
В PlayerController также имеется список важных унаследованных переменных, которые Вы можете использовать в своей работе в Unreal Engine.
Я чаще всего использую переменную Player Camera Manager, возвращающую ссылку на объект базового класса PlayerCameraManager. С помощью данного класса мы имеем возможность настраивать камеру для текущего PlayerController.
Работу с данной переменной мы рассмотрим на примере ниже в данной статье в разделе «Практика в Unreal Engine №3».
Также в контроллере игрока доступны и другие унаследованные переменные:
- Player Camera Manager Class — возвращает текущий класс PlayerCameraManagerClass;
- Smooth Target View Rotation Speed (float) — возвращает скорость интерполяции смешивания поворота Target View для более плавного обновления клиента. Target View — Актор, через который PlayerController смотрит на мир. Также через эту переменную можно задать текущее значение Smooth Target;
- Player Is Waiting (bool) — возвращает True, если PlayerController ожидает начала матча или возрождения. Используется только в режиме наблюдения;
- Should Perform Full Tick when Paused (bool) — возвращает True, если разрешено исполнять функцию Tick, когда игра поставлена на паузу. Также через эту переменную можно задать текущее значение данного параметра.
Как создать и подключить контроллер игрока в Анрил Энджин
Создать собственный класс контроллера игрока достаточно легко. Для этого нужно в «Content Drawer» вызвать контекстное меню через правую клавишу мышки и перейти в пункт «Blueprint Class». Далее в окне «Pick Parent Class» выбрать класс Player Controller.
Но, важный вопрос на самом деле не в том, как создать Player Controller, а как подключить его к объектам Pawn и Character.
Чтобы подключить или произвести смену контроллера персонажа в Unreal Engine (UE4, UE5), нужен файл GameMode. Именно в нем подключается Player Controller для персонажа по умолчанию (при старте игры).
Итак, откройте файл GameMode, который используется в Вашем проекте. Перейдите в меню «Class Defaults», далее во вкладку «Details» и в раздел «Classes». В этом разделе найдите настройки «Player Controller Class» и в выпадающем списке выберите свой класс контроллера. Таким образом можно подключить Player Controller для персонажа в UE5 (UE4).
Если в Вашем проекте файл GameMode отсутствует, его необходимо создать по аналогии с процессом, описанным выше для контроллера игрока. И после подключить GameMode в настройках Вашего проекта: «Edit / Project Settings / Maps & Modes / Default GameMode».
Как получить Player Controller персонажа в UE5. Функция Get Player Controller
Получить контроллер игрока для персонажа мы можем при помощи Blueprint-функции «Get Player Controller».
В Unreal Engine функция «Get Player Controller» возвращает ссылку на объект базового родительского класса PlayerController для указанного игрока. Поскольку игроков может быть несколько, то функция производит поиск как среди локальных, так и среди доступных удаленных игроков.
Если функция вызывается на сетевом клиенте, то поиск осуществляется только локально, и возвращается клиентский PlayerController. В случае, когда функция вызывается на прослушивающем сервере, она возвращает контроллер этого прослушивающего сервера. Если же функция вызывается на выделенном сервере, то возвращается первый клиентский PlayerController, который был найден на этом сервере.
Входящие параметры:
- Player Index (Int, по умолчанию 0) — индекс в списке контроллеров игрока (сначала идут локальные, а затем доступные удаленные).
Так как функция возвращает ссылку именно на базовый родительский класс движка Unreal Engine, то необходимо данную ссылку при помощи Cast (каста) привести к типу Вашего пользовательского класса контроллера игрока, чтобы получить доступ ко всем его функциям и переменным.
Ниже представлен Blueprint-код, в котором с помощью ноды «Get Player Controller» мы получаем ссылку на объект базового контроллера игрока. Затем, используя функцию приведения типов «Cast to BP_MyPlayerController», преобразуем эту ссылку в наш пользовательский объект «BP_MyPlayerController». И сохраняем его в переменной «As BP My Player Controller». Таким образом, в этой переменной мы получили объект контроллера игрока для текущего персонажа в UE5 (UE4).
Скриншот
Код на BlueprintUE
Также есть возможность получить пользовательский PlayerController через Blueprint Interface (интерфейсы Unreal Engine). Этот вариант предпочтительнее, но немного сложнее. В этом случае необходимо дополнительно создать свою интерфейсную функцию «Get Custom PlayerController» и реализовать её в пользовательском классе контроллера игрока «BP_CustomPlayerController».
Скриншот
Код на BlueprintUE
Override functions. Переопределение событий в Player Controller
В классе PlayerController, в разделе «Function / Override», находятся системные события, которые можно переопределить. Иначе говоря, в этих событиях по умолчанию уже описана определённая системная логика, которую Вы, исходя из Ваших потребностей, можете изменить. В данном разделе перечислены функции и события, унаследованные как от класса Actor, так и от класса контроллера игрока.
Override functions от Actor мы уже обсуждали в соответствующей статье, сейчас же сосредоточимся на разборе событий переопределения для рассматриваемого в этой статье класса Player Controller.
- Event On Possess
Событие «On Possess» вызывается при получении PlayerController контроля над овладеваемым Pawn (Character).
Входящий параметр:
Possessed Pawn — ссылка на объект базового класса Pawn, которым начал владеть контроллер.
Переопределение события «OnPossess» мы рассмотрим на примере ниже в данной статье в разделе «Практика в Unreal Engine №2».
- Event On UnPossess
Событие «On UnPossess» вызывается при утрате PlayerController контроля над Pawn (Character).
Входящий параметр:
Unpossessed Pawn — ссылка на объект базового класса Pawn, который освободился от управления контроллером.
Переопределение события «OnUnPossess» мы рассмотрим на примере ниже в данной статье в разделе «Практика в Unreal Engine №2».
- Receive Instigated Any Damage
Событие «Receive Instigated Any Damage» инициируется, когда контроллер наносит какой-либо урон другому актору. Вызывается только на сервере.
Входящие параметры:
Damage (float) — значение наносимого урона.
Damage Type — ссылка на объект базового класса DamageType. Тип наносимого повреждения.
Damaged Actor — ссылка на объект базового класса Actor, которому нанесёно повреждение.
Damage Causer — ссылка на объект базового класса Actor, который наносит ущерб.
Функции Possess и Un Possess
Чтобы произвести в Unreal Engine смену персонажа у контроллера через код Blueprints используйте ноды «Possess» и «Un Possess».
Blueprint-функция «Possess» присоединяет к PlayerController указанный во входных параметрах новый Pawn (Character). Она запускается только на сервере (если функция HasAuthority() возвращает значение True). При смене контроллером находящегося во владении Pawn, оба Pawn’а получают соответствующие уведомления о произошедшей смене. А именно, у них вызываются события «Event Possessed» и «Event Unpossessed».
Blueprint-функция «Un Possess» отсоединяет указанный PlayerController от управляемого им Pawn.
Входящие значения:
- Target (ссылка на объект контроллера, по умолчанию self) — в этом параметре нужно указать PlayerController, для которого функция «Possess» будет устанавливать контроль над новым Pawn. А «Un Possess» — отсоединять контролируемый Pawn.
- In Pawn (ссылка на объект Pawn) — в этом параметре нужно указать новый Pawn, которым будет управлять контроллер.
Рассмотрим смену персонажа у контроллера игрока с помощью функции «Possess» на практике.
Практика в Unreal Engine №1. Смена персонажа у PlayerController через Blueprint
Задача: предоставить возможность игроку в ходе игры менять своего персонажа на одного из двух, представленных на текущем уровне.
Ниже представлен Blueprint-код, в котором при помощи ноды «Possess» мы у PlayerController меняем управляемых персонажей. Сами персонажи представлены в игровом мире двумя объектами одного и того же класса «BP_ThirdPersonCharacter».
Смена персонажей вызывается в EventGraph контроллера игрока по нажатию на клавиатуре клавиши «C». Далее нодой «Get Player Character» мы получаем текущего персонажа класса Character. При помощи каста приводим тип Character к нашему пользовательскому классу «BP_ThirdPersonCharacter». Далее удаляем этот объект из массива акторов класса «BP_ThirdPersonCharacter», который предварительно вернула нода «Get All Actor Of Class».
Поскольку мы удалили из массива текущий Pawn, которым владеет PlayerController, то теперь в этом массиве можно свободно выбрать Pawn под номером 0. И, используя функцию «Possess», прикрепить его к PlayerController, тем самым меняя его владение.
Скриншот
Код на BlueprintUE
Практика в Unreal Engine №2. Переопределение событий «On Possess» и «On UnPossess» в классе PlayerController
Данный практический пример является логическим продолжением 1 примера, который описывался в разделе выше.
Задача: при смене игроком первого персонажа на второго в его интерфейсе (HUD) должен появиться виджет с надписью «Второй игрок». Когда игрок возвращается к первому персонажу, этот виджет нужно удалить.
Первым шагом будет создание самого виджета с надписью «Второй игрок». Для этого создадим виджет WB_HUD, в который и добавим нужную надпись. Но здесь я не буду подробно описывать данный процесс, чтобы не отвлекаться от основной темы.
Согласно условиям задачи, нам необходимо отображать виджет с надписью только на втором персонаже. Чтобы как-то выделить этого персонажа, присвоим ему тег 2 в разделе Actor настроек Details.
Далее весь код мы будем размещать в Event Graph, в классе Player Controller.
Итак, при возникновении события «Event Begin Play» создадим в оперативной памяти объект нового виджета. Для этого воспользуемся нодой «Create WB Hud Widget», в настройках которой зададим класс нашего виджета WB_HUD. После этого сохраним созданный объект виджета в переменной WB_HUD, чтобы иметь возможность обращаться к нему в дальнейшем.
Скриншот
Код на BlueprintUE
Далее переопределим событие «Event On Possess». Напоминаю, данное событие вызывается при получении PlayerController контроля над Pawn. Это именно то, что нам нужно. Когда мы переключаемся на другого персонажа, будет происходить вызов этого события. Причём «Event On Possess» в своём параметре будет возвращать нам объект нового подконтрольного Pawn.
Теперь нам нужно проверить, есть ли у возвращенного Pawn тег 2. Для этого воспользуемся функцией «Actor Has Tag». Если Pawn действительно содержит этот тег, то с помощью ноды «Add to Viewport» добавим виджет на экран игрока. В качестве входящего параметра для этой ноды мы укажем ранее созданную переменную, которая содержит объект виджета WB_HUD с надписью «Второй игрок».
Скриншот
Код на BlueprintUE
Таким образом, мы вывели виджет с текстом при переходе ко второму персонажу. Теперь необходимо удалить этот виджет, когда пользователь снова перейдёт к первому персонажу.
Код будет похож на предыдущий. Нам необходимо переопределить событие «Event On UnPossess», которое срабатывает при потере контроллера своего подконтрольного Pawn. Когда это событие вызывается, нам нужно удалить с экрана наш ранее созданный виджет. Для этого воспользуемся нодой «Remove from Parent», которая удалит наш объект виджета. Чтобы нода отработала, передадим ей сам объект виджета, который хранится в переменной WB_HUD.
Однако, поскольку событие «Event On UnPossess» будет запускаться и при потере контроля над первым персонажем, у которого переменная WB_HUD окажется пустой, чтобы избежать ошибок, необходимо преобразовать эту переменную в тип «Validated Get».
Для этого щёлкните правой кнопкой мыши по переменной WB_HUD и в появившемся контекстном меню выберите пункт «Convert to Validated Get». После этого переменная превратится в ноду с двумя выходами: Is valid (переменная содержит объект виджета) и Not is Valid (переменная пуста). Функцию «Remove from Parent» следует подключить к выходу Is valid, чтобы обеспечить корректное выполнение задачи.
Скриншот
Код на BlueprintUE
Итак, воспользовавшись переопределением событий «On Possess» и «On UnPossess» в Player Controller, мы встроили в них свой код и тем самым при переходе с одного персонажа на другой создали новую собственную функциональность.
Практика в Unreal Engine №3. Ограничиваем Pitch камеры у игрока. Player Camera Manager
По умолчанию в Анрил Энджин угол обзора у камеры персонажа настроен довольно-таки широко — на 180 градусов (от -90 до 90). Что не всегда правильно. Ведь камера спускается прям под ноги персонажа…
Задача: ограничить Pitch камеры у Player Controller.
Чтобы ограничить движение Pitch камеры в игре, нужно обратиться к объекту класса менеджера камеры внутри контроллера игрока. В этом классе следует задать параметры минимального и максимального угла поворота камеры.
Сделать это можно через унаследованную переменную «Player Camera Manager», в Event Graph класса Player Controller. Эта переменная возвратит текущий объект менеджера камеры. Затем, используя методы «Set View Pitch Min» и «Set View Pitch Max», нужно задать необходимые значения: для минимума — «-75», а для максимума — «55».
Весь этот процесс ставим на выполнение в событии «Event BeginPlay«, чтобы настройка ограничения Pitch камеры совершилась один раз при старте игры.
Скриншот
Код на BlueprintUE
На этом мы завершаем нашу статью. В ней мы обсудили Blueprint-класс, отвечающий за контроллер игрока — PlayerController в Unreal Engine (UE4, UE5). Рассмотрели, для чего он нужен, как его использовать и как настроить. Также разобрали несколько практических примеров кода на Blueprint, чтобы Вы могли лучше понять возможности данного класса.