5.9 KiB
UItemRegistrySubsystem
基本信息
- 类型: UCLASS
- 父类: UGameInstanceSubsystem
- 源文件: Plugins/Item/Source/Item/Public/ItemRegistrySubsystem.h
- 模块: Item
功能概述
GameInstance作用域的中心注册表。管理物品定义DataTable的注册以及按属性名称注册视图策略。Initialize()从UItemRegistrySettings自动加载。提供GetItemDef和GetViewStrategy查找。
设计用意
物品元数据的运行时服务定位器。UGameInstanceSubsystem确保全局生命周期。从项目设置自动加载(设计师配置,无需代码变更)。提供动态内容的运行时注册API。
职责范围
物品定义和视图策略的中心查找。注册/注销DataTable和策略。不创建物品或视图(委托给工厂类)。
项目内依赖
| 依赖项 | 关系 | 源文件 |
|---|---|---|
| ItemFactory.h | #include (在.cpp中) | Plugins/Item/Source/Item/Public/ItemFactory.h |
| ItemRegistrySettings.h | #include (在.cpp中) | Plugins/Item/Source/Item/Public/ItemRegistrySettings.h |
对外接口
UItemRegistrySubsystem 是 UGameInstanceSubsystem,通过 GetGameInstance()->GetSubsystem() 获取(参见 DefaultContainer.cpp:44-52 的静态辅助函数 GetRegistry)。
DataTable 管理(BlueprintCallable):
- RegisterDataTable(FName Key, UDataTable)*: 以指定键名注册一个 DataTable。初始化时自动从 UItemRegistrySettings::ItemDataTables 加载(ItemRegistrySubsystem.cpp:8-13)。
- UnregisterDataTable(FName Key): 移除指定键名的 DataTable(ItemRegistrySubsystem.cpp:15-17)。
视图策略管理(BlueprintCallable):
- RegisterViewStrategy(FName PropertyName, const TScriptInterface&): 为指定属性名注册视图策略。初始化时自动从 UItemRegistrySettings::ViewStrategies 加载并实例化(ItemRegistrySubsystem.cpp:20-25)。
- UnregisterViewStrategy(FName PropertyName): 移除指定属性名的视图策略(ItemRegistrySubsystem.cpp:27-29)。
查询接口(BlueprintCallable):
- GetItemDef(FName ItemType) const → FItemDef: 遍历所有已注册的 DataTable,通过 FindRow 查找指定类型名称的物品定义。返回 FItemDef 值副本。未找到时返回默认构造的空 FItemDef(其 ItemName 为空,调用方可据此判断结果有效性)(ItemRegistrySubsystem.cpp:32-42)。
- GetViewStrategy(FName PropertyName) const → TScriptInterface: 从策略映射中查找指定属性名的策略。未找到时返回空的 TScriptInterface(ItemRegistrySubsystem.cpp:45-52)。
生命周期:
- Initialize(FSubsystemCollectionBase&): GameInstance 子系统初始化时自动调用。读取 UItemRegistrySettings 单例,加载所有软引用的 DataTable 和策略类并注册。加载完成后输出日志(ItemRegistrySubsystem.cpp:54-81)。
使用方法
UItemRegistrySubsystem 作为 GameInstance 子系统,在游戏启动时自动初始化。访问方式如下。
获取注册表(DefaultContainer.cpp:44-52):
static UItemRegistrySubsystem* GetRegistry(const UObject* WorldContext)
{
if (!WorldContext) return nullptr;
UWorld* World = WorldContext->GetWorld();
if (!World) return nullptr;
UGameInstance* GI = World->GetGameInstance();
if (!GI) return nullptr;
return GI->GetSubsystem<UItemRegistrySubsystem>();
}
在任何需要的地方调用此辅助函数即可获取注册表单例。
查询物品定义:
UItemRegistrySubsystem* Registry = GetRegistry(this);
FItemDef Def = Registry->GetItemDef(ItemType);
if (Def.ItemName.IsEmpty()) { /* 未找到 */ }
查询视图策略:
// ItemViewFactory.cpp:70
TScriptInterface<IItemViewStrategy> Strategy =
Registry->GetViewStrategy(Desc.Name);
if (!Strategy.GetInterface()) continue; // 策略不存在则跳过
自动初始化流程(ItemRegistrySubsystem.cpp:54-81):
- 游戏启动时,GameInstance 创建所有子系统。
- Initialize 被调用,读取 UItemRegistrySettings 单例。
- 遍历 ItemDataTables,LoadSynchronous 每个软引用并注册。
- 遍历 ViewStrategies,LoadSynchronous 每个类,NewObject 实例化并注册。
- 输出日志报告注册的 DataTable 和策略数量。
运行时动态注册: 除了自动初始化外,也可在运行时调用 RegisterDataTable / RegisterViewStrategy 动态注册(如 DLC 内容加载后补充物品定义)。
用例
Plugins/Item/Source/Item/Public/ItemRegistrySubsystem.h:15-43-- UItemRegistrySubsystem 类声明(公开方法 + 私有 TMap 成员)。Plugins/Item/Source/Item/Private/ItemRegistrySubsystem.cpp:8-13-- RegisterDataTable 实现。Plugins/Item/Source/Item/Private/ItemRegistrySubsystem.cpp:15-17-- UnregisterDataTable 实现。Plugins/Item/Source/Item/Private/ItemRegistrySubsystem.cpp:20-25-- RegisterViewStrategy 实现。Plugins/Item/Source/Item/Private/ItemRegistrySubsystem.cpp:27-29-- UnregisterViewStrategy 实现。Plugins/Item/Source/Item/Private/ItemRegistrySubsystem.cpp:32-42-- GetItemDef 实现:遍历所有 DataTable 查找物品定义。Plugins/Item/Source/Item/Private/ItemRegistrySubsystem.cpp:45-52-- GetViewStrategy 实现:从 ViewStrategyMap 查找策略。Plugins/Item/Source/Item/Private/ItemRegistrySubsystem.cpp:54-81-- Initialize 实现:从 UItemRegistrySettings 加载配置并自动注册 DataTable 和策略。Plugins/Item/Source/Item/Private/DefaultContainer.cpp:44-52-- GetRegistry 辅助函数,通过 GI->GetSubsystem() 获取注册表。Plugins/Item/Source/Item/Private/DefaultContainer.cpp:57,71,115-- GetItemViews / GetItemViewByID / CreateItem 中获取注册表并调用 GetItemDef。Plugins/Item/Source/Item/Private/ItemViewFactory.cpp:70-- CreateView 中调用 Registry->GetViewStrategy(Desc.Name) 获取属性格式化策略。