# 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):** ```cpp 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(); } ``` 在任何需要的地方调用此辅助函数即可获取注册表单例。 **查询物品定义:** ```cpp UItemRegistrySubsystem* Registry = GetRegistry(this); FItemDef Def = Registry->GetItemDef(ItemType); if (Def.ItemName.IsEmpty()) { /* 未找到 */ } ``` **查询视图策略:** ```cpp // ItemViewFactory.cpp:70 TScriptInterface Strategy = Registry->GetViewStrategy(Desc.Name); if (!Strategy.GetInterface()) continue; // 策略不存在则跳过 ``` **自动初始化流程(ItemRegistrySubsystem.cpp:54-81):** 1. 游戏启动时,GameInstance 创建所有子系统。 2. Initialize 被调用,读取 UItemRegistrySettings 单例。 3. 遍历 ItemDataTables,LoadSynchronous 每个软引用并注册。 4. 遍历 ViewStrategies,LoadSynchronous 每个类,NewObject 实例化并注册。 5. 输出日志报告注册的 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) 获取属性格式化策略。