子系统
Subsystems
子系统 (Subsystem) 是自动实例化、生命周期绑定在宿主对象上的类:Engine、Editor、GameInstance、World、LocalPlayer 五种。宿主创建时自动创建并 Initialize(),宿主关闭时 Deinitialize(),之后无引用即被 GC。它替代了「继承 GameInstance 塞管理器」的老做法,自带按类型的蓝图节点和 Python 访问,特别适合插件。官方编程页只列四种,World 子系统依据 5.8 Python API 补充。
为什么要子系统
官方:子系统 (Subsystem) 是自动实例化、生命周期受管理的类,提供易用的扩展点,立即获得蓝图和 Python 暴露,同时避免修改或继承引擎类。理由包括:节省编码、避免继承引擎类、避免往已经很臃肿的类(如 GameInstance)上加 API、蓝图中有按类型的智能节点(无需 Cast)、Python 访问、模块化;对插件尤其有用——用户启用插件即可,作者明确知道它何时被实例化和初始化。(Programming Subsystems)这是对 Gameplay 框架 中「继承 GameInstance 塞管理器」老做法的替代。
五种生命周期
| 子系统基类 | 生命周期绑定 | 获取方式 |
|---|---|---|
UEngineSubsystem | 引擎;模块 Startup() 返回后 Initialize(),Shutdown() 返回后 Deinitialize() | GEngine->GetEngineSubsystem<T>() |
UEditorSubsystem | 编辑器;同上 | GEditor->GetEditorSubsystem<T>() |
UGameInstanceSubsystem | GameInstance | GameInstance->GetSubsystem<T>() |
UWorldSubsystem | UWorld | World->GetSubsystem<T>()(UE 5.8 API,另有静态重载 UWorld::GetSubsystem<T>(World),找不到时返回 nullptr;UWorldSubsystem / UWorld::GetSubsystem API) |
ULocalPlayerSubsystem | 本地玩家 | LocalPlayer->GetSubsystem<T>() |
前四行除 World 外均来自官方 Programming Subsystems 页;该页的生命周期表只列了 Engine、Editor、GameInstance、LocalPlayer 四种。World 子系统依据 UE 5.8 Python API:UWorldSubsystem 是「与 UWorld 共享生命周期的自动实例化、自动初始化系统」的基类,FWorldSubsystemCollection 负责为已初始化的世界调用 PostInitialize 和 OnWorldBeginPlay。(Programming Subsystems)
生命周期(以 GameInstance 为例)
sequenceDiagram participant GI as UGameInstance participant S as UMyGamesSubsystem GI->>S: GameInstance 创建后,自动创建子系统实例 GI->>S: GameInstance 初始化 → Initialize(Collection) GI->>S: GameInstance 关闭 → Deinitialize() Note over S: 引用被释放,若无其他引用则被 GC 回收
(Programming Subsystems)最后一步意味着:别在外部长期强引用子系统,否则它会比宿主活得更久;GC 规则见 垃圾回收与对象生命周期。
用法
UCLASS()
class UMyGamesStatsSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
void IncrementResourceStat();
};
(官方示例,Programming Subsystems)需要蓝图访问的函数照常加 UFUNCTION() 标记,见 蓝图与 C++ 协作、UObject 与反射系统。Python 用 unreal.get_engine_subsystem(...)、unreal.get_editor_subsystem(...)(官方注明 Python 为实验性功能)。
选哪种
| 需要的寿命 | 选择 | 典型 |
|---|---|---|
| 跨关卡、整个游戏会话 | GameInstance | 存档、成就统计、在线会话 |
| 跟当前关卡/世界走 | World | 关卡内的全局管理器(生成、天气) |
| 每个本地玩家一份 | LocalPlayer | 输入映射、UI 管理(分屏) |
| 引擎/编辑器全局 | Engine / Editor | 工具、资产处理、编辑器脚本 |
(典型用途为通识归纳;增强输入的映射上下文本身就通过 LocalPlayer 子系统添加,见 增强输入。)
坑
- 编辑器中 PIE、编辑器世界、预览世界都是 UWorld,World 子系统会为它们各自创建;需要过滤时重写
DoesSupportWorldType(EWorldType),默认的ShouldCreateSubsystem会调用它判断(UE 5.8 API)。World 子系统还有额外的生命周期回调:PostInitialize(所有 World 子系统初始化之后)、OnWorldBeginPlay(在所有 Actor 的 BeginPlay 之前)、OnWorldEndPlay、PreDeinitialize;需要 Tick 时继承UTickableWorldSubsystem(UWorldSubsystem / UWorld::GetSubsystem API)。 - Engine/Editor 子系统所在模块的加载阶段决定初始化时机,见 模块、插件与构建系统。
出处
- Programming Subsystems UE 5.8 文档
- UWorldSubsystem / UWorld::GetSubsystem API UE 5.8 API 参考