# 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 | 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: 根据物品定义创建并返回一个新的物品实例。 **参数说明:** - ItemDef: 物品的 DataTable 行定义,提供默认属性、显示信息等。 - ItemType: 物品类型名称(通常与 DataTable 行名一致),写入 FItemInstance::ItemType。 - OverrideProps: 可选的特化属性集。传入 nullptr 则仅使用 ItemDef 中的 DefaultItemProps。非空时,会在 DefaultItemProps 基础上合并覆盖值(同一属性名会被覆盖)。 **返回值:** 返回 TUniquePtr。创建的物品实例具有以下特征: - 自动生成唯一 ItemID(FGuid::NewGuid())。 - ItemData 已填充 DefaultItemProps + OverrideProps 的合并属性。 - 如果 ItemDef.bHasTracer 为 true,ItemData 中额外包含 Internal_ItemTracer 键的 UItemTracer 对象。 **调用限制:** 此方法是创建 FItemInstance 的唯一入口。FItemInstance 的构造函数是 private/default(通过 friend class ItemFactory 控制),外部代码无法直接构造 FItemInstance。 ## 使用方法 ItemFactory 的唯一使用场景是通过 UDefaultContainer::CreateItem 创建物品。 **调用 CreateItemInstance(DefaultContainer.cpp:121):** ```cpp bool UDefaultContainer::CreateItem(FName ItemType, TArray& 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 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。 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 的唯一外部调用点。