Files
loneseDocument/Plugins/Item/ItemFactory.md
meishibiezb 29a3f77908 init
2026-06-04 21:44:13 +08:00

4.7 KiB
Raw Blame History

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。创建的物品实例具有以下特征

  • 自动生成唯一 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

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。
  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 的唯一外部调用点。