This commit is contained in:
meishibiezb
2026-06-04 21:37:53 +08:00
parent b0d2a0e2e7
commit 29a3f77908
63 changed files with 4068 additions and 1 deletions

View File

@@ -0,0 +1,85 @@
# ItemFactory
## 基本信息
- **类型**: C++ 静态类非UCLASS
- **父类**: (无)
- **源文件**: Plugins/Item/Source/Item/Public/ItemFactory.h
- **模块**: Item
## 功能概述
用于创建FItemInstance对象的纯静态工厂。唯一公开方法CreateItemInstance生成GUID、将FItemDef::DefaultItemProps转换为属性包、可选合并覆盖项并在bHasTracer为true时添加UItemTracer。为FItemInstance的友元类。
## 设计用意
集中化、单一入口的物品创建。确保每个物品都有有效GUID、已填充的默认值和一致的Tracer设置。友元访问阻止外部代码构造未初始化的物品。
## 职责范围
仅负责物品实例化。接收FItemDef + 类型名称返回TUniquePtr<FItemInstance>。私有辅助方法处理属性转换和合并。
## 项目内依赖
| 依赖项 | 关系 | 源文件 |
|--------|------|--------|
| FItemInstance | friend class | Plugins/Item/Source/Item/Public/ItemFactory.h |
| FItemDef | 参数类型 | Plugins/Item/Source/Item/Public/ItemFactory.h |
| UInternalItemProperty | 调用 | Plugins/Item/Source/Item/Public/ItemFactory.h |
| UItemTracer | 创建 (NewObject) | Plugins/Item/Source/Item/Public/ItemFactory.h |
## 对外接口
ItemFactory 是纯 C++ 静态类(非 UCLASS仅提供一个公开静态方法作为物品创建的唯一入口
- **CreateItemInstance(const FItemDef& ItemDef, FName ItemType, const FInstancedPropertyBag* OverrideProps = nullptr)** → TUniquePtr<FItemInstance>: 根据物品定义创建并返回一个新的物品实例。
**参数说明:**
- ItemDef: 物品的 DataTable 行定义,提供默认属性、显示信息等。
- ItemType: 物品类型名称(通常与 DataTable 行名一致),写入 FItemInstance::ItemType。
- OverrideProps: 可选的特化属性集。传入 nullptr 则仅使用 ItemDef 中的 DefaultItemProps。非空时会在 DefaultItemProps 基础上合并覆盖值(同一属性名会被覆盖)。
**返回值:**
返回 TUniquePtr<FItemInstance>。创建的物品实例具有以下特征:
- 自动生成唯一 ItemIDFGuid::NewGuid())。
- ItemData 已填充 DefaultItemProps + OverrideProps 的合并属性。
- 如果 ItemDef.bHasTracer 为 trueItemData 中额外包含 Internal_ItemTracer 键的 UItemTracer 对象。
**调用限制:**
此方法是创建 FItemInstance 的唯一入口。FItemInstance 的构造函数是 private/default通过 friend class ItemFactory 控制),外部代码无法直接构造 FItemInstance。
## 使用方法
ItemFactory 的唯一使用场景是通过 UDefaultContainer::CreateItem 创建物品。
**调用 CreateItemInstanceDefaultContainer.cpp:121**
```cpp
bool UDefaultContainer::CreateItem(FName ItemType,
TArray<FGuid>& NewItemIDs, int32 Count)
{
UItemRegistrySubsystem* Registry = GetRegistry(this);
if (!Registry) return false;
FItemDef Def = Registry->GetItemDef(ItemType);
if (Def.ItemName.IsEmpty()) return false;
for (int32 i = 0; i < Count; ++i)
{
TUniquePtr<FItemInstance> NewItem =
ItemFactory::CreateItemInstance(Def, ItemType);
if (!NewItem) return false;
NewItemIDs.Add(NewItem->ItemID);
this->InjectPayload(MoveTemp(NewItem));
}
return true;
}
```
**调用链:**
1. 外部通过 IItemContainer::CreateItem 请求创建。
2. UDefaultContainer::CreateItem 从注册表获取 FItemDef验证有效性。
3. 调用 ItemFactory::CreateItemInstance(Def, ItemType) → TUniquePtr<FItemInstance>。
4. 工厂内部:生成 GUID → 转换默认属性 → 合并覆盖属性 → 按需创建 Tracer。
5. 容器通过自身的 InjectPayload 将物品注入存储。
**不直接调用的场景:**
ItemFactory 不应被直接调用。所有物品创建都应通过容器的 CreateItem 接口,确保物品被正确注入容器并更新 Tracer。
## 用例
- `Plugins/Item/Source/Item/Public/ItemFactory.h:127-140` -- ItemFactory 类声明CreateItemInstance 公开方法 + ConvertDefaultProps / MergePropertyBag 私有方法)。
- `Plugins/Item/Source/Item/Private/ItemFactory.cpp:6-24` -- CreateItemInstance 完整实现:生成 GUID → 转换默认属性 → 合并覆盖属性 → 按需创建 Tracer。
- `Plugins/Item/Source/Item/Private/ItemFactory.cpp:26-48` -- ConvertDefaultProps 实现:遍历 FItemPropertyEntry 数组,从 ValuePicker 读取值并写入 FInstancedPropertyBag。
- `Plugins/Item/Source/Item/Private/ItemFactory.cpp:51-84` -- MergePropertyBag 实现:将源属性包的所有属性合并到目标属性包(同名覆盖)。
- `Plugins/Item/Source/Item/Private/DefaultContainer.cpp:121` -- UDefaultContainer::CreateItem 调用 ItemFactory::CreateItemInstance 的唯一外部调用点。