Unreal EngineJuniorTechnical
Что такое класс GameMode и какова его ответственность?
GameMode — singleton-класс сервера, определяющий правила игры: какие классы использовать для Pawn, PlayerController, HUD, GameState, PlayerState; существует только на сервере и не реплицируется клиентам.
Что такое GameMode
AGameModeBase / AGameMode — это класс-«арбитр» игровой сессии. Он создаётся один раз при старте уровня и существует только на сервере (включая выделенный сервер и listen-сервер). Клиенты экземпляр GameMode не получают — для передачи данных клиентам используется AGameState.
Ответственности GameMode
- Регистрация классов: задаёт, какие классы UE должна создавать для Pawn, PlayerController, HUD, GameState, PlayerState, SpectatorPawn.
- Правила спавна игроков:
GetDefaultPawnClassForController(),ChoosePlayerStart(),RestartPlayer(). - Логика начала/конца матча:
StartPlay(),ReadyToStartMatch(),EndMatch()(только вAGameMode, не в Base). - Авторизация входа:
PreLogin(),Login(),PostLogin(),Logout(). - Определение победителя, счёта, правил победы.
AGameModeBase vs AGameMode
AGameModeBase— минималистичная база без матчевого стейт-машины (Waiting → InProgress → End). Используйте для простых игр.AGameModeдобавляетMatchState(FName), событияHandleMatchIsWaitingToStart,HandleMatchHasStarted,HandleMatchHasEnded, поддержкуbDelayedStart.
Пример кастомного GameMode
// MyGameMode.h
#pragma once
#include "GameFramework/GameModeBase.h"
#include "MyGameMode.generated.h"
UCLASS()
class MYGAME_API AMyGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
AMyGameMode();
virtual void PostLogin(APlayerController* NewPlayer) override;
virtual AActor* ChoosePlayerStart_Implementation(
AController* Player) override;
};
// MyGameMode.cpp
#include "MyGameMode.h"
#include "MyPlayerController.h"
#include "MyCharacter.h"
#include "MyHUD.h"
AMyGameMode::AMyGameMode()
{
DefaultPawnClass = AMyCharacter::StaticClass();
PlayerControllerClass = AMyPlayerController::StaticClass();
HUDClass = AMyHUD::StaticClass();
// GameStateClass и PlayerStateClass тоже задаются здесь
}
void AMyGameMode::PostLogin(APlayerController* NewPlayer)
{
Super::PostLogin(NewPlayer);
UE_LOG(LogTemp, Log, TEXT("Player joined: %s"),
*NewPlayer->GetName());
}
Назначение GameMode уровню
В настройках уровня (World Settings → GameMode Override) или в DefaultEngine.ini:
[/Script/EngineSettings.GameMapsSettings]
GlobalDefaultGameMode=/Script/MyGame.MyGameMode
Подводные камни
- GameMode на клиенте:
GetWorld()->GetAuthGameMode()возвращаетnullptrна клиенте — обращение к нему вызовет краш. - Смешение GameMode и GameState: данные, которые нужны клиентам (счёт, оставшееся время), должны жить в GameState с репликацией, а не в GameMode.
- Изменение DefaultPawnClass во время игры: смена класса не влияет на уже заспавненных пешек; нужно вручную удалить и заново заспавнить.
- Override уровня перебивает проектные настройки: GameMode Override в World Settings имеет приоритет над DefaultEngine.ini — легко забыть при добавлении нового уровня.
- Вызов матч-методов на AGameModeBase: методы
SetMatchState,RestartGameесть только вAGameMode; попытка привести Base к Game без проверки — краш.
Common mistakes
- Объяснять GameMode только по синтаксису, без жизненного цикла и стоимости.
- Игнорировать ошибки, null/empty состояния, порядок инициализации или режим сборки.
- Давать пример, который работает в демо, но ломается при изменении владельца ресурса.
- Использовать макросы или specifier-и наугад и забывать про UObject GC.
What the interviewer is testing
- Кандидат формулирует точную модель для GameMode, а не только определение.
- Пример компилируем, безопасен по lifetime и соответствует версии технологии.
- Названы trade-off, ограничения и диагностируемые симптомы ошибки.
- Понимает границу между C++ кодом, runtime/framework metadata и editor/UI слоем.