Player State в Unreal Engine

Друзья, приветствую, с Вами Будуев Антон. В данной статье мы обсудим класс Player State, отвечающий в движке Unreal Engine (UE4, UE5) за хранение информации о состоянии конкретного отдельно взятого игрока.

Вскоре выйдет моя бесплатная книга по Blueprints для Unreal Engine в PDF формате. Как она выйдет, рекомендую её скачать, чтобы Вы детально изучили блюпринты Анрил Энджин.

Player State

Player State (состояние игрока) — это класс в Unreal Engine, объект которого предназначен для хранения, репликации и управления состоянием игрока в многопользовательской игре. Он отделяет логическую информацию об игроке — такую как имя, счёт, пинг, уникальный идентификатор и статус — от его физического представления в виде Pawn.

Объект PlayerState создаётся на сервере для каждого подключённого игрока, включая ботов и зрителей, а в однопользовательской или автономной игре — для локального игрока и реплицируется на всех клиентов.

После своего создания на сервере PlayerState добавляется в специальный массив активных игроков Player Array внутри объекта Game State, обеспечивая централизованное хранение данных о каждом игроке. Поскольку PlayerState является реплицируемым Актором, его ключевые свойства — такие как имя, счёт, статус и пинг — синхронизируются на всех клиентах, формируя единое сетевое представление всех участников сессии.

Таблица распределения классов фреймфорка Unreal Engine (UE4, UE5) по тому, где существует объект этого класса. В данном случае Player State существует как на сервере, так и на всех клиентах.
Таблица распределения классов фреймфорка Unreal Engine (UE4, UE5) по тому, где существует объект этого класса. В данном случае Player State существует как на сервере, так и на всех клиентах.

Перевод официальной справки: Player State создается для каждого игрока на сервере (или в автономной игре). Реплицируются на всех клиентах и содержат информацию, связанную с сетевой игрой, такую как имя игрока, счёт и т.д.

Blueprint-свойства класса Player State

Свойства класса Player State
Свойства класса Player State
  • Score — служит для отслеживания игрового счёта игрока. Поскольку оно реплицируется, счёт каждого игрока будет синхронизирован между сервером и всеми клиентами. Это позволяет отображать табло с очками в реальном времени у всех участников, а также использовать его в игровой логике (например, для определения победителя).
  • PlayerID — локальный идентификатор игрока в рамках сессии в виде 32-битного целого числа, который реплицируется с сервера на клиентов только один раз (при создании Player State).
  • Compressed Ping реплицируемое свойство, хранящее усреднённый пинг игрока, сжатый в байт и масштабированный (разделённый) в 4 раза для оптимизации сетевого трафика. Оно реплицируется всем клиентам, кроме владельца, и используется для отображения и логики сетевого пинга в игре, обеспечивая при этом экономию пропускной способности. Для локального владельца или сервера используется другое значение — ExactPing (точное значение пинга в миллисекундах).
  • Is Spectator реплицируемое свойство, которое указывает, находится ли игрок в статусе зрителя (Spectator). Оно автоматически синхронизируется сервером со всеми клиентами, позволяя в игре корректно отображать и учитывать этот статус для всех участников сессии.
  • Is A Bot — реплицируемое свойство, которое указывает, связан ли данный PlayerState с искусственным интеллектом (AI Controller), то есть представляет ли игрок бота. Данное свойство синхронизируется сервером со всеми клиентами (при создании PlayerState), обеспечивая корректное разделение игроков и ботов в игре.
  • Pawn Private — приватный указатель (ссылка) на Pawn, который связан с текущим PlayerState. Свойство не реплицируется напрямую. Для доступа к свойству используется функция Get Pawn.

Ключевая функциональность класса Player State

  • Storage and Replication Player State — хранение и репликация игровой информации о игроке.
    • Имя (PlayerNamePrivate);
    • Счёт (Score);
    • Пинг (CompressedPing, ExactPing);
    • Идентификаторы (PlayerId, UniqueId);
    • Статусы (IsSpectator, IsABot, OnlySpectator);
    • Время начала (StartTime).
  • Network Replication Callbacks — сетевая репликация Callback-ов для обновления состояния игрока при его изменениях (OnRep_Score, OnRep_PlayerName, OnRep_PlayerId, OnRep_UniqueId и др.).
  • Ping — управление пингом игрока, включая накопление и усреднение значений пинга для более стабильного отображения задержки через структуру PingAvgData и методы UpdatePing и RecalculateAvgPing.
  • Player Identifiers — обработка уникальных идентификаторов игроков с помощью UniqueNetIdRepl, включая регистрацию и отмену регистрации игроков в сессиях через методы RegisterPlayerWithSession и UnregisterPlayerWithSession.
  • Support for Seamless Travel — поддержка функционала плавного перехода между уровнями (Seamless Travel) с возможностью копирования состояния игрока из предыдущего PlayerState в новый (SeamlessTravelTo, CopyProperties, OverrideWith).
  • Customization of Player Name — поддержка кастомизации имени игрока через флаг UseCustomPlayerNames и виртуальные методы для получения пользовательского имени (GetPlayerNameCustom).
  • Welcome Messages — отправка приветственных сообщений. При подключении игрока или смене имени рассылает локализованные сообщения (вход, смена имени, выход).

Наследование классов

В Unreal Engine класс Player State наследуется от класса Info, добавляя главным образом функциональность хранения и управления состоянием игрока. Сам же класс Info наследуется от Actor (базовый класс для объектов, размещаемых на игровом уровне).

Info — абстрактный класс для Акторов, которые не имеют физического представления в мире и используются для хранения информации и управления игровыми системами.

Общее наследование класса состояния игрока: Actor > Info > Player State
Общее наследование класса состояния игрока: Actor > Info > Player State

Как создать и подключить PlayerState в Unreal Engine

Чтобы создать свой собственный пользовательский класс состояния игрока, откройте Content Browser и щелкните правой кнопкой мыши по пустому полю. В появившемся контекстном меню выберите пункт Blueprint Class. Затем в открывшемся окне Pick Parent Class введите в поисковую строку «Player State». Далее выделите класс PlayerState и нажмите Select. В результате в текущей папке Content Browser будет создан ассет базового класса состояния игрока.

Создание пользовательского blueprint класса Player State в Unreal Engine (UE4, UE5)
Создание пользовательского blueprint класса Player State в Unreal Engine (UE4, UE5)

Само подключение класса состояния игрока производится в классе Game Mode.

Откройте ассет пользовательского класса Game Mode, который используется в проекте. Перейдите в меню Class Defaults, далее во вкладку Details и в раздел Classes. В этом разделе найдите настройки Player State Class. И в выпадающем списке выберите необходимый класс состояния игрока.

Установка пользовательского класса PlayerState в GameMode
Установка пользовательского класса PlayerState в GameMode

Как получить текущий Player State в Unreal Engine

Функция Get Player State

Blueprint-функция Get Player State
Blueprint-функция Get Player State

Blueprint-функция Get Player State позволяет из любого класса в Blueprint получить текущий класс состояния игрока. Функция возвращает ссылку на объект базового родительского класса PlayerState. Работает как на клиенте, так и на сервере. При этом индекс остаётся неизменным.

Входящее параметры:

  • Player State Index (int, по умолчанию 0) — индекс PlayerState в PlayerArray (массив игроков, доступный в классе Game State).

Player State Object Reference

Player State Object Reference
Player State Object Reference

Player State Object Reference — переменная, возвращающая ссылку на объект базового родительского класса PlayerState. Доступна только в классах Pawn (Character) и Player Controller.

Если данная переменная вызывается в Pawn, то она возвращает ссылку на объект PlayerState только тогда, когда этот Pawn находится под контролем PlayerController. Применяется для сетевой игры, поскольку контроллеры не реплицируются на удалённых клиентов.

Если переменная вызывается в PlayerController, то она возвращает ссылку на объект PlayerState, содержащий реплицированную информацию об игроке, использующем данный контроллер (доступно только для игроков, не для NPC).

Player Array

Массив PlayerArray в Unreal Engine
Массив PlayerArray в Unreal Engine

Player Array — переменная класса Game State, содержащая массив всех доступных в текущий момент Player State на сервере и клиентах. Вызывается только из класса Game State.

Blueprint-события класса Player State

Blueprint-события класса Player State
Blueprint-события класса Player State
  • Event Copy Properties — событие вызывается в процессе переноса данных между двумя объектами PlayerState — старым и новым, например, во время смены уровней. Позволяет разработчику в Blueprint дополнительно скопировать или перенести любые специфичные для проекта свойства и данные из текущего (старого) PlayerState в новый экземпляр PlayerState. Вызывается в старом PlayerState.
  • Event Override With — событие, позволяющее при переподключение игрока скопировать дополнительные свойства из старого PlayerState в новый. Вызывается в новом PlayerState.

Blueprint-функции класса Player State

Blueprint-функции класса Player State
Blueprint-функции класса Player State
  • Get Unique Net Id — предоставляет уникальный сетевой идентификатор игрока, который сохраняется на протяжении всей сессии и синхронизируется между всеми игроками в мультиплеере. Используется для однозначного определения игрока в онлайн-сервисах.
  • Get Pawn — возвращает ссылку на Pawn, которым управляет игрок, связанный с этим PlayerState.
  • Get Ping In Milliseconds — значения пинга игрока в миллисекундах с учётом сетевой репликации и оптимизации передачи данных. Предоставляет точный пинг для локальных игроков и сервера, и приближённое сжатое значение для удалённых клиентов.
  • Get Player Controller — возвращает ссылка на объект Player Controller, владеющего этим PlayerState, с учётом особенностей сетевой архитектуры и различий между локальными и удалёнными игроками. Если вызвана на стороне клиента для чужого игрока, вернёт Null.
  • Get Player Name — возвращает текущее имя игрока, связанного с этим PlayerState.
  • Is Only ASpectator — возвращает текущее значение свойства Only Spectator, отвечающего за статус игрока как зрителя (Spectator).

Практика в Unreal Engine

Получаем список ID всех сетевых игроков

В данном практическом примере мы используем 2 ноды, связанные с рассматриваемым в данной статье классом PlayerState. А именно, ноду Player Array из класса Game State, с помощью которой мы получим список всех PlayerState, доступных в текущей сетевой игре. И функцию Get Player ID, возвращающую идентификационный номер игрока.

Задача: в сетевой игре, нажав на клавиатуре клавишу C, вывести на сервере список всех идентификаторов игроков, которые в данный момент находятся в игре.

Задача в Unreal Engine: получить список ID всех сетевых игроков
Задача в Unreal Engine: получить список ID всех сетевых игроков

Итак, Blueprint-код решения данной задачи я буду прописывать в Event Graph в персонаже BP_ThirdPersonCharacter.

Чтобы код выполнялся исключительно на сервере, создадим Custom Event (пользовательское событие) Get ALL Player ID. В настройках Details данного события укажем, что оно должно запускаться только на сервере. То есть для свойства Replicates установим значение Run on Server.

Событие Get ALL Player ID: свойство Replicates выставляем на Run on Server
Событие Get ALL Player ID: свойство Replicates выставляем на Run on Server

После чего запустим это событие по нажатию на клавишу C.

Запускаем пользовательское событие Get All Player Id по нажатию на клавишу C
Запускаем пользовательское событие Get All Player Id по нажатию на клавишу C

Далее опишем функциональность нашего пользовательского события Get ALL Player ID.

С помощью функции Get Game State получим доступ к базовому классу Game State. Из него мы можем вызвать переменную Player Array. Она вернёт нам массив всех состояний игроков, присутствующих на сервере и клиентах. Чтобы получить доступ к конкретному состоянию игрока, мы можем перебрать весь массив с помощью цикла For Each Loop. На выходе Array Element этого цикла мы получим ссылку на объект состояния конкретного игрока.

В классе PlayerState уже определены ряд свойств, характеризующих сетевых игроков. Среди них есть необходимое нам свойство Player ID. Чтобы получить доступ к этому значению, вызовем функцию Get Player ID из объекта PlayerState, который возвращает ранее созданный цикл For. Затем нам остаётся лишь вывести полученный ID игрока с помощью функции Print String.

Скриншот

Практический пример на Unreal Engine: получаем список ID всех сетевых игроков. Функции Get Game State, Player Array и Get Player ID
Практический пример на Unreal Engine: получаем список ID всех сетевых игроков. Функции Get Game State, Player Array и Get Player ID

Код на BlueprintUE

Если код отображается без связей, нажмите сверху кода на кнопку «Graph» Если код отображается без связей, нажмите сверху кода на кнопку "Graph"


Таким образом, перебрав в цикле For Each Loop все доступные в массиве объекты PlayerState, мы на каждом повторе цикла по каждому этому объекту выводим его ID на экран сервера.

Копирование информации из старого Player State в новый при переходе на другой уровень. События Event Copy Properties и Event Override With

Для примера рассмотрим блюпринт-код копирования информации переменной Count Score из старого объекта Player State в новый при переходе на другой игровой уровень. Данный код будет находится в Event Graph в пользовательском классе BP_ CustomPlayerState.

  1. Event Copy Properties
    1. Итак, для копирования информации при переходе с уровня на уровень, воспользуемся переопределением события Event Copy Properties. При вызове данного события во выходном пине возвратится объект нового Player State из нового уровня. Само же событие будет вызвано еще в старом PlayerState до перехода на следующий уровень.
    2. Далее, так как мы переопределяем это событие, чтобы воспользоваться всем его функционалом из родительского класса, подсоединим ноду Parent: CopyProperties, вызвав её через правую клавишу мыши, кликнув по Event Copy Properties.
    3. Затем с помощью Cast преобразуем возвращаемый параметр New Player State из Event Copy Properties в объект пользовательского класса BP_CustomPlayerState, который вернёт нам новый пользовательский объект PlayerState. Далее в нём с помощью функции SET установим значение переменной Count Score, передав туда значение Count Score из текущего (старого) PlayerState.
  2. Event Override With
    1. Для копирования информации при повторном подключении игрока воспользуемся переопределением события Event Override With. При вызове данного события во выходном пине возвратится объект старого PlayerState из предыдущего уровня. Само же событие будет вызвано уже в новом Player State уже после повторного подключения игрока.
    2. Далее, по аналогии с предыдущим 1 пунктом, подключим к событию ноду Parent: Override With.
    3. Затем с помощью Cast преобразуем возвращаемый параметр Old Player State из Event Override With в объект пользовательского класса BP_CustomPlayerState, который вернёт нам старый пользовательский объект PlayerState. Далее из него с помощью функции GET извлечём значение переменной Count Score. И наконец, передадим это значение в Count Score текущего (нового) PlayerState.

Скриншот

Unreal Engine: копируем информацию из старого объекта Player State в новый при помощи двух переопределяемых событий Event Copy Properties и Event Override With
Unreal Engine: копируем информацию из старого объекта Player State в новый при помощи двух переопределяемых событий Event Copy Properties и Event Override With

Код на BlueprintUE

Если код отображается без связей, нажмите сверху кода на кнопку «Graph» Если код отображается без связей, нажмите сверху кода на кнопку "Graph"


Совет. Вскоре выйдет моя бесплатная книга по Blueprints для Unreal Engine в PDF формате. Как она выйдет, рекомендую её скачать, чтобы Вы детально изучили блюпринты Анрил Энджин.


наш Телеграм канал

Оцените статью
( 2 оценки, среднее 5 из 5 )
Поделитесь этой статьей со своими знакомыми в социальных сетях, возможно, эта статья кому-то будет полезна
Unreal Engine - это просто
Добавить комментарий

Нажимая на кнопку "Отправить комментарий", я даю согласие на обработку персональных данных и принимаю политику конфиденциальности.