Game Instance в Unreal Engine

Друзья, приветствую, с Вами Будуев Антон. В данной статье мы обсудим Game Instance — класс экземпляра игры в Unreal Engine (UE4, UE5).

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

Game Instance

Game Instance (экземпляр игры) — специальный класс в Unreal Engine, который существует на протяжении всего времени работы игры и не уничтожается при смене уровней (карт). Основное назначение Game Instance — хранить и управлять данными и состоянием, которые должны сохраняться между загрузками разных уровней.

Перевод официальной справки: Game Instance — объект высокого уровня для управления запущенным экземпляром игры. Создается при запуске игры и уничтожается только при ее завершении. При запуске как автономной игры будет создан один такой экземпляр. При запуске в режиме «проигрывания в редакторе» (PIE) будет создан один экземпляр на каждый сеанс PIE.

Game Instance является центральным долгоживущим объектом, который представляет собой «контейнер» для всей игровой сессии. Он создается в начале работы игры и существует до ее завершения. Также класс содержит специфичную для редактора логику — когда в редакторе нажимается Play, Unreal Engine создает отдельный экземпляр Game Instance для симуляции в редакторе (Play-In-Editor, PIE).

Ключевая особенность данного класса — устойчивость к смене уровней (World). В отличие от большинства игровых объектов, которые существуют в пределах одного уровня (World), Game Instance продолжает существовать, когда игрок переходит с одной карты на другую. Это делает его идеальным местом для хранения данных и логики, которые должны сохраняться между уровнями.

Класс отвечает за инициализацию и деинициализацию ключевых игровых систем, таких как управление сессиями (OnlineSession), таймеры (TimerManager), отложенные действия (LatentActionManager) и подсистемы (GameInstanceSubsystem). Он также является центральным узлом для управления локальными игроками (LocalPlayer), которые представляют игроков, подключенных к этой машине (включая SplitScreen).

Отличия Game Instance от других классов Unreal Engine

Главное отличие Game Instance от остальных классов заключается в том, что он существует на протяжении всей сессии игры — создаётся при запуске и уничтожается только при завершении приложения. В отличие от большинства игровых объектов, объект данного класса не меняется и не удаляется при смене уровней.

Ещё одна особенность проявляется в редакторе Blueprints. При работе с классом экземпляра игры вы не увидите стандартных вкладок Construction Script и Viewport, привычных для большинства Blueprint-классов. Вместо этого доступна только одна вкладка — Event Graph. Также отсутствует возможность добавлять компоненты, как это возможно в других классах, например, в наследниках Actor.

Всё это связано с тем, что Game Instance наследуется напрямую от базового класса Object, а не от Actor, как большинство других Blueprint-классов. Следовательно, он не содержит стандартных элементов и функционала, унаследованных от Акторов. Например, в данном классе нет автоматического периодического обновления (Tick), так как данный функционал реализуется в Акторах.

Game Instance наследуется напрямую от класса Object
Game Instance наследуется напрямую от класса Object

Кроме того, во вкладке Event Graph класса GameInstance отсутствуют многие распространённые события Unreal Engine, такие как Event BeginPlay или Event Tick, которые характерны для Actor и его наследников. Вместо этого, в Blueprints доступны специфичные для GameInstance события, такие как Init, Shutdown, Network Error и Travel Error.

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

  • Game Lifecycle — создаётся при запуске игры и существует до её завершения. Ключевые методы жизненного цикла, управляющие инициализацией и очисткой ресурсов Init(), Shutdown(), StartGameInstance().
  • Persistence — не пересоздаётся при смене уровней, что позволяет хранить данные и состояние между переходами.
  • Global Data — позволяет сохранять состояние игры, прогресс, настройки и любые пользовательские данные. Доступен из всех классов через функцию GetGameInstance().
  • Local Players — управляет локальными игроками (LocalPlayer): создание, добавление, удаление и поиск. Поддерживает Split-Screen. Но сами игровые сущности (Player Controller / Pawn) определяются и создаются уже на уровне Game Mode.
  • Session Management — отвечает за создание, поиск и подключение к мультиплеерным сессиям через объект OnlineSession.
  • Networking — координирует и инициирует некоторые сетевые действия (включая запуск Listen-сервера и переход к сессии). Действует как высокоуровневый менеджер, который настраивает параметры и делегирует выполнение более специализированным объектам (World, PlayerController, OnlineSession).
  • Level Travel — управляет загрузкой начального уровня. Участвует в процессе обработки переходов.
  • Game Mode Creation — предоставляет возможность кастомизировать логику выбора или создания класса игрового режима (Game Mode) при загрузке уровня путем переопределения виртуальной функции CreateGameModeForURL().
  • Subsystems — является владельцем подсистем уровня игры (GameInstanceSubsystem).
  • Replay System — предоставляет удобный и централизованный интерфейс для работы с подсистемой реплеев (ReplaySubsystem).
  • PlayInEditor (PIE) — реализует логику для запуска игры внутри редактора Unreal, создавая отдельный экземпляр игры для каждого сеанса.
  • Timers & Latent Actions — предоставляет доступ к управлению таймерами и отложенными действиями через TimerManager и LatentActionManager, которые и являются основой для всей системы отложенного и асинхронного выполнения кода в Unreal Engine, как в C++, так и в Blueprints (Set Timer by Function Name, Delay и т.д.).
  • Input Handling — отслеживает подключение и отключение устройств ввода с помощью специальных делегатов.

Blueprint-события класса Game Instance

Blueprint-события класса Game Instance
Blueprint-события класса Game Instance
  • Event Init — вызывается движком один раз при создании экземпляра GameInstance и даёт возможность пользовательским подклассам инициализировать свои параметры и настроить внутреннее состояние перед началом игры.
  • Event Shutdown — вызывается при закрытии или завершении работы экземпляра GameInstance и предоставляет возможность подклассам выполнить необходимые действия по очистке ресурсов и подготовке к завершению игры.
  • Event Travel Error — событие, которое позволяет обработать ошибки при переходе между уровнями (Travel) в игре. Используется для обработки различных типов ошибок загрузки или перемещения на новый уровень.
  • Event Network Error — событие, позволяющее обрабатывать ошибки сети во время игры. Используется для обработки различных типов сетевых сбоев, учитывая, произошёл сбой на сервере или на клиенте.

Диспетчеры событий (Delegates) класса Game Instance

Диспетчеры событий (Delegates) класса Game Instance
Диспетчеры событий (Delegates) класса Game Instance
  • On Input Device Connection Change — событие, которое вызывается каждый раз, когда происходит изменение состояния подключения устройства ввода, например, когда игрок подключает или отключает геймпад, джойстик или другое устройство.
  • On Pawn Controller Changed — событие автоматически вызывается после связывания контроллера с Pawn, с учётом возможности повторных вызовов в ситуациях с сетевой репликацией.
  • On User Input Device Pairing Change — событие вызывается всякий раз, когда происходит изменение привязки устройства ввода к пользователю платформы. Проще говоря, это уведомление о том, что у конкретного устройства ввода сменился владелец (пользователь).

Как создать и подключить класс Game Instance

Чтобы создать свой собственный класс экземпляра игры, откройте Content Browser и щелкните правой кнопкой мыши по пустому пространству. В появившемся контекстном меню выберите опцию Blueprint Class. В открывшемся окне Pick Parent Class введите в поисковую строку «Game Instance». После этого выделите класс GameInstance и нажмите Select. В результате в текущей папке Content Browser будет создан ассет, представляющий базовый класс экземпляра игры.

Создание пользовательского Blueprint-класса GameInstance в Unreal Engine (UE4, UE5)
Создание пользовательского Blueprint-класса GameInstance в Unreal Engine (UE4, UE5)

Чтобы подключить пользовательский класс экземпляра игры, перейдите в свойства проекта Edit / Project Settings, раздел Maps & Modes и далее в опции Game Instance установите свой класс экземпляра игры.

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

Как получить класс экземпляра игры. Функция Get Game Instance

Blueprint-функция Get Game Instance
Blueprint-функция Get Game Instance

Get Game Instance — это Blueprint-функция в Unreal Engine, которая возвращает объект (экземпляр) GameInstance, ассоциированный с текущим игровым миром. Она позволяет получить доступ к данным и функционалу экземпляра игры, который существует на протяжении всей сессии и не уничтожается при смене уровней.

Функция доступна и вызывается из любого объекта, имеющего World Context Object (Actor, Pawn, Character, Player Controller и др.).

Если требуется работа с пользовательским классом GameInstance, для возвращаемого функцией Get Game Instance значения необходимо выполнить приведение типа (Cast) к этому пользовательскому классу — либо, для большей гибкости, использовать интерфейсы (Unreal Interfaces), реализованные в пользовательском классе GameInstance.

Практика GameInstance. Сохраняем выбранного персонажа между загрузкой разных уровней

Итак, давайте рассмотрим практическое применение класса Game Instance в Unreal Engine. Как я уже упоминал ранее, основная цель этого класса — сохранить информацию между загрузками уровней.

Так вот, задача заключается в том, чтобы на текущем игровом уровне выбрать одного из двух персонажей: мужчину SKM_Manny или женщину SKM_Quinn. Причём этот выбор должен сохраниться при переходе на следующий уровень игры.

Переоткрытие уровня в Unreal Engine

Для простоты описания кода в этой статье мы рассмотрим процесс загрузки различных уровней, используя для этого один и тот же уровень под названием ThirdPersonMap, который является частью стандартного шаблона игры от третьего лица в Unreal Engine. Чтобы упростить процесс, мы будем постоянно открывать этот уровень заново.

Для этого во вкладке Event Graph персонажа BP_ThirdPersonCharacter мы добавим ноду Open Level, которая будет отвечать за переоткрытие уровня ThirdPersonMap при нажатии клавиши L.

Открытие нового уровня ThirdPersonMap в Unreal Engine по нажатию на клавишу L
Открытие нового уровня ThirdPersonMap в Unreal Engine по нажатию на клавишу L

Создание пользовательского класса экземпляра игры

Чтобы иметь возможность переносить выбранного персонажа между уровнями, создадим свой собственный класс экземпляра игры CustomGameInstance. В этом классе определим новую переменную SkeletalMesh типа SkeletalMeshObject. Именно в этой переменной мы и будем хранить нашего персонажа внутри экземпляра игры. Установим для переменной значение по умолчанию, выбрав ассет женского персонажа SKM_Quinn.

Переменная SkeletalMesh внутри пользовательского класса CustomGameInstance
Переменная SkeletalMesh внутри пользовательского класса CustomGameInstance

Установка сохранённого персонажа из Game Instance

Каждый раз при загрузке нового уровня мы будем считывать значение переменной SkeletalMesh из CustomGameInstance и устанавливать его в Mesh текущего персонажа BP_ThirdPersonCharacter.

Для решения этой задачи идеально подойдёт функция Construction Script внутри BP_ThirdPersonCharacter. Поскольку она активируется только один раз — в момент размещения объекта на уровне. А наш персонаж как раз появляется на уровне во время его загрузки.

Итак, в Construction Script обратимся к базовому классу Game Instance. С помощью приведения типа (Cast) преобразуем его в Custom Game Instance. Затем получим доступ к переменной Skeletal Mesh, которая хранится внутри нашего игрового экземпляра. И, наконец, присвоим значение этой переменной компоненту Mesh текущего персонажа BP_ThirdPersonCharacter.

Таким образом, каждый раз, когда мы загружаем новый уровень, персонаж будет автоматически восстанавливаться из ранее сохранённой переменной в рамках экземпляра игры.

Скриншот

При открытии нового уровня загружаем персонажа из сохраненной переменной внутри Game Instance
При открытии нового уровня загружаем персонажа из сохраненной переменной внутри Game Instance

Код на BlueprintUE

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


Смена персонажа и его сохранение в GameInstance

Затем во вкладке Event Graph персонажа BP_ThirdPersonCharacter назначим на клавишу C процесс изменения пола персонажа с женского на мужской и обратно. Это изменение будет сохранено в переменной SkeletalMesh внутри класса Custom GameInstance.

Нода Flip Flop будет обрабатывать нажатие на клавишу C, и при каждом последующем нажатии попеременно запускать код, устанавливающий то мужской, то женский пол.

Сам процесс установки персонажа будет похож на код из Construction Script, который мы уже рассмотрели ранее. Однако вместо того, чтобы читать значение переменной, мы будем сохранять выбранного персонажа в этой переменной. И после уже устанавливать этого персонажа в компоненте Mesh в BP_ThirdPersonCharacter.

Скриншот

Практика GameInstance. Сохраняем в Unreal Engine (UE4, UE5) выбранного персонажа между загрузкой разных уровней
Практика GameInstance. Сохраняем в Unreal Engine (UE4, UE5) выбранного персонажа между загрузкой разных уровней

Код на BlueprintUE

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


Таким образом, используя класс GameInstance, мы сохраняем нашего персонажа в переменной SkeletalMesh, что позволяет нам затем загружать его на разных уровнях игры.

Проблема данной практики

Пример из урока отлично иллюстрирует концепцию хранения данных между уровнями с помощью класса Game Instance. Однако для настройки персонажа в примере используется Construction Script. На самом деле, полагаться на него можно только тогда, когда логика ограничена внутренним состоянием Актора. При работе с внешними зависимостями — необходимо выбирать Begin Play, а также обеспечивать проверку на валидность (Is Valid). А почему так? Обсудим в статье про скрипт построения: перейти к объяснению Construction Script.

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


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

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

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