96 lines
5.9 KiB
Markdown
96 lines
5.9 KiB
Markdown
# 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<UItemRegistrySubsystem>() 获取(参见 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<IItemViewStrategy>&)**: 为指定属性名注册视图策略。初始化时自动从 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<IItemViewStrategy>: 从策略映射中查找指定属性名的策略。未找到时返回空的 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<UItemRegistrySubsystem>();
|
||
}
|
||
```
|
||
在任何需要的地方调用此辅助函数即可获取注册表单例。
|
||
|
||
**查询物品定义:**
|
||
```cpp
|
||
UItemRegistrySubsystem* Registry = GetRegistry(this);
|
||
FItemDef Def = Registry->GetItemDef(ItemType);
|
||
if (Def.ItemName.IsEmpty()) { /* 未找到 */ }
|
||
```
|
||
|
||
**查询视图策略:**
|
||
```cpp
|
||
// ItemViewFactory.cpp:70
|
||
TScriptInterface<IItemViewStrategy> 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<UItemRegistrySubsystem>() 获取注册表。
|
||
- `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) 获取属性格式化策略。
|