虚幻引擎GameMode详解

虚幻引擎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 通过一系列可重写函数,串起了玩家进入游戏到离开的整个生命周期。

玩家登录流程

  1. PreLogin – 在接受连接前调用,可用于验证密码、检查服务器是否已满,拒绝则返回错误信息。

  2. Login – 创建 PlayerController,并返回给新玩家。

  3. PostLogin – 玩家成功登入后触发,适合在这里初始化玩家数据,或通知其他玩家。

生成玩家与 Pawn

  1. HandleStartingNewPlayer – 在 PostLogin 后调用,内部通常会去调用 RestartPlayer

  2. RestartPlayer – 负责在指定的 PlayerStart 处重生玩家。

  3. SpawnDefaultPawnFor – 被 RestartPlayer 调用,实际生成默认 Pawn 的函数。如果你需要自定义 Pawn 生成逻辑(如根据角色职业生成不同 Pawn),最常重写的就是它。

  4. ChoosePlayerStart – 决定玩家在哪个出生点出现,可用来实现队伍出生点、随机出生点。

游戏进程

  1. StartPlay – Actor 全部加载完毕,游戏正式开始前调用,是初始化游戏逻辑的好地方。

  2. HasMatchStarted / HasMatchEnded – 判断比赛是否已开始/结束。

  3. ReadyToStartMatch / ReadyToEndMatch – 检查是否满足开始/结束条件。

  4. EndMatch – 主动结束比赛,进入 WaitingPostMatch 状态。

蓝图里也有对应的 K2_ 前缀事件,如 Event OnPostLoginEvent 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

  1. 内容浏览器 → 右键 → 蓝图类 → 选择 Game Mode Base 或 Game Mode 作为父类。

  2. 命名为 BP_MyGameMode,打开它。

  3. 在类默认值(Class Defaults)里设置 Default Pawn ClassHUD Class 等。

  4. 在事件图表中,重写 Event OnPostLoginEvent OnRestartPlayer 等节点,实现自己的逻辑。

创建 C++ GameMode

cpp
// 头文件
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 就是服务端唯一的“规则书”。记住三句话:

  1. 它只活在服务器,客户端看不见。

  2. 它负责决策(何时开始、谁赢了、生成哪个 Pawn)。

  3. 它通过设置默认类来控制 PlayerController、Pawn、HUD、GameState 等全家桶。

感谢您的来访,获取更多精彩文章请收藏本站。

THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容