虚幻引擎5中,GameMode 是定义游戏规则与服务端核心逻辑的基石。它只存在于服务器上,负责管理玩家加入、生成 Pawn、判定胜负等关键流程,可以说是整个游戏运行的“裁判”。
下面从核心概念、类层次、职责流程、实战用法等几个方面为你详细拆解。
1. 核心定位:只存在于服务器的“裁判”
这是理解 GameMode 最重要的一点:GameMode 只存在于服务端,客户端上没有它的实例。
这意味着:
-
所有游戏规则、胜负判定、玩家生成逻辑都应该写在 GameMode 中。
-
如果要让客户端看到游戏状态(比如比分、剩余时间),不能直接放在 GameMode 里,必须通过 GameState 来同步。
-
可以直接在 GameMode 中安全地执行权限操作,比如授予物品、改变玩家生命值(通过服务器 RPC)。
2. 类层次:AGameModeBase 与 AGameMode
UE5 提供了两个基类,你通常从这里继承:
-
AGameModeBase
最基础的 GameMode,适合所有类型的游戏,包括单人和多人。没有内置的状态机,逻辑更轻量。新建项目默认使用它。 -
AGameMode(继承自 AGameModeBase)
在基础之上添加了比赛状态机:WaitingToStart→InProgress→WaitingPostMatch→LeavingMap等,以及处理玩家等待、比赛开始倒计时、比赛结束等流程。适合有明确回合/场次结构的竞技游戏(如射击、MOBA)。
选择建议:简单游戏用
GameModeBase,需要“等待玩家-开始比赛-结束比赛”流程时用GameMode。
3. 核心职责与流程
GameMode 通过一系列可重写函数,串起了玩家进入游戏到离开的整个生命周期。
玩家登录流程
-
PreLogin – 在接受连接前调用,可用于验证密码、检查服务器是否已满,拒绝则返回错误信息。
-
Login – 创建
PlayerController,并返回给新玩家。 -
PostLogin – 玩家成功登入后触发,适合在这里初始化玩家数据,或通知其他玩家。
生成玩家与 Pawn
-
HandleStartingNewPlayer – 在 PostLogin 后调用,内部通常会去调用
RestartPlayer。 -
RestartPlayer – 负责在指定的
PlayerStart处重生玩家。 -
SpawnDefaultPawnFor – 被
RestartPlayer调用,实际生成默认 Pawn 的函数。如果你需要自定义 Pawn 生成逻辑(如根据角色职业生成不同 Pawn),最常重写的就是它。 -
ChoosePlayerStart – 决定玩家在哪个出生点出现,可用来实现队伍出生点、随机出生点。
游戏进程
-
StartPlay – Actor 全部加载完毕,游戏正式开始前调用,是初始化游戏逻辑的好地方。
-
HasMatchStarted / HasMatchEnded – 判断比赛是否已开始/结束。
-
ReadyToStartMatch / ReadyToEndMatch – 检查是否满足开始/结束条件。
-
EndMatch – 主动结束比赛,进入
WaitingPostMatch状态。
蓝图里也有对应的
K2_前缀事件,如Event OnPostLogin、Event OnRestartPlayer等,方便直接使用。
4. GameMode 与核心类的协作
在 GameMode 中,你可以直接指定本局游戏使用的默认类,这是它控制全局配置的关键:
| 属性 | 作用 | 典型设置 |
|---|---|---|
| Default Pawn Class | 默认生成的 Pawn 类型 | 你的角色蓝图/类 |
| Player Controller Class | 玩家控制器类型 | 自定义的 MyPlayerController |
| Game State Class | 游戏状态类(需同步数据放这里) | MyGameState |
| Player State Class | 玩家状态类(分数、名字等) | MyPlayerState |
| HUD Class | 客户端界面 HUD | MyHUD |
| Spectator Class | 观战者 Pawn | 自定义观战类 |
这些设置在蓝图或 C++ 的构造函数里赋值,就会覆盖整个地图的默认值。
与 GameState 的配合
-
GameMode 负责判断(例如“击杀数达到30,游戏结束”)。
-
GameState 负责记录和同步这些数据(当前击杀数、剩余时间),因为它会被复制到所有客户端,供 UI 等使用。
-
所以通常的写法是:GameMode 里处理击杀事件,更新 GameState 上的“总击杀数”属性,然后 GameMode 检测 GameState 的数值来决定是否结束。
5. 如何创建并使用自定义 GameMode
创建蓝图 GameMode
-
内容浏览器 → 右键 → 蓝图类 → 选择
Game Mode Base或Game Mode作为父类。 -
命名为
BP_MyGameMode,打开它。 -
在类默认值(Class Defaults)里设置
Default Pawn Class、HUD Class等。 -
在事件图表中,重写
Event OnPostLogin、Event OnRestartPlayer等节点,实现自己的逻辑。
创建 C++ GameMode
// 头文件 UCLASS() class MYGAME_API AMyGameMode : public AGameModeBase { GENERATED_BODY() public: AMyGameMode(); virtual void PostLogin(APlayerController* NewPlayer) override; virtual AActor* ChoosePlayerStart_Implementation(AController* Player) override; }; // CPP 文件 AMyGameMode::AMyGameMode() { // 设置默认类 static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBP(TEXT("/Game/Blueprints/BP_MyCharacter")); if (PlayerPawnBP.Succeeded()) { DefaultPawnClass = PlayerPawnBP.Class; } }
设置生效
-
全局默认:编辑 → 项目设置 → 地图和模式 → 默认 GameMode,选你的蓝图/类。
-
单个地图覆盖:打开地图,在世界场景设置(World Settings)中,修改“GameMode Override”。
-
通过 URL 加载:执行
open LevelName?game=/Game/Path/BP_MyGameMode命令时动态指定。
6. UE5 注意事项与最佳实践
-
永远不要在 GameMode 里存储需要客户端显示的数据。GameMode 不存在于客户端,客户端读取不到。请放入
GameState或PlayerState,并用RepNotify或GetLifetimeReplicatedProps同步。 -
大世界/World Partition 兼容:UE5 的 World Partition 不影响 GameMode 核心逻辑,但如果你在数据层或关卡流送中动态生成 Actor,确保 GameMode 依然能通过
ChoosePlayerStart找到有效出生点。可使用AGameModeBase::FindPlayerStart的逻辑,它会基于 APlayerStart Actor 的标签过滤。 -
使用 GameMode 组件(UE5.1+):实际上,UE5 更推荐将规则模块化,你可以创建
UGameplayAbilitySystem或自定义 Actor 组件来组织逻辑,但 GameMode 依然是规则的入口和持有者。 -
避免在客户端调用 GameMode 函数。如果你在客户端调用
GetGameMode(),会返回nullptr。客户端逻辑应通过PlayerController发 RPC 到服务器,再由服务器 GameMode 处理。
总结
GameMode 就是服务端唯一的“规则书”。记住三句话:
-
它只活在服务器,客户端看不见。
-
它负责决策(何时开始、谁赢了、生成哪个 Pawn)。
-
它通过设置默认类来控制 PlayerController、Pawn、HUD、GameState 等全家桶。
感谢您的来访,获取更多精彩文章请收藏本站。









暂无评论内容