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

6.3 KiB
Raw Permalink Blame History

UDefaultContainer

基本信息

  • 类型: UCLASS(BlueprintType, Blueprintable)
  • 父类: UObject, 实现 IItemContainer
  • 源文件: Plugins/Item/Source/Item/Public/DefaultContainer.h
  • 模块: Item

功能概述

IItemContainer的参考实现。将物品存储在TArray<TUniquePtr>中。实现所有接口方法查询、移动、创建、带类型检查的属性读写。Blueprintable允许设计师扩展。TODO计划切换为TMap以提升性能。

设计用意

默认的具体容器实现。简单的扁平数组存储。Blueprintable标记允许子类添加约束槽位、堆叠。为其他容器实现提供参考。

职责范围

完整的IItemContainer实现。处理物品存储、检索、移动、创建和属性访问。使用UItemRegistrySubsystem进行物品定义查找使用FItemViewFactory生成视图。

项目内依赖

依赖项 关系 源文件
ItemContainer.h #include (实现) Plugins/Item/Source/Item/Public/ItemContainer.h
ItemRegistrySubsystem.h #include (在.cpp中) Plugins/Item/Source/Item/Public/ItemRegistrySubsystem.h
ItemViewFactory.h #include (在.cpp中) Plugins/Item/Source/Item/Public/ItemViewFactory.h
ItemFactory.h #include (在.cpp中) Plugins/Item/Source/Item/Public/ItemFactory.h

对外接口

UDefaultContainer 实现了 IItemContainer 的全部接口,对外暴露以下方法(全部继承自 IItemContainer此处列出的均为 override 实现):

查询接口:

  • GetItemViews() const → TArray: 遍历内部 Items 数组,通过 UItemRegistrySubsystem 获取每个物品的 FItemDef调用 FItemViewFactory::CreateView 构造视图。注册表不可用时返回空数组DefaultContainer.cpp:54-66
  • GetItemViewByID(const FGuid&) const → FItemView: 按 ID 查找。未找到返回空 FItemViewDefaultContainer.cpp:69-81
  • GetItemCount() const → int32: 返回 Items.Num()DefaultContainer.cpp:84-86

变更接口:

  • MoveItem(const FGuid&, const TScriptInterface&) → bool: 从内部数组取出物品MoveTemp调用 RemoveAt然后通过目标容器的 InjectPayload 注入。目标容器无效或物品不存在时返回 falseDefaultContainer.cpp:89-111
  • CreateItem(FName, TArray&, int32 Count = 1) → bool: 从注册表获取 FItemDef检查 ItemName 非空,循环调用 ItemFactory::CreateItemInstance 创建指定数量物品,每个物品通过自身的 InjectPayload 添加。新物品 ID 追加到 NewItemIDsDefaultContainer.cpp:113-127

属性接口CustomThunk 底层实现):

  • Internal_GetPropertyRaw: 按 ItemID 线性查找物品 → 从属性包中查找属性描述 → 类型兼容性检查后从属性包内存拷贝到蓝图引脚内存DefaultContainer.cpp:137-187
  • Internal_SetPropertyRaw: 相同的查找和类型检查流程反向拷贝从蓝图引脚写入属性包DefaultContainer.cpp:189-230

内部接口:

  • InjectPayloadImpl(TUniquePtr): 接收物品所有权,简单的 Items.AddDefaultContainer.cpp:129-135

存储: 内部使用 TArray<TUniquePtr> Items 存储物品。当前为线性查找O(n)TODO 计划切换为 TMap 以提升性能。类标记为 BlueprintType 和 Blueprintable可在编辑器中创建 BP_DefaultContainer 子类。

使用方法

UDefaultContainer 作为 IItemContainer 的参考实现,可直接在 C++ 中实例化,或创建 Blueprint 子类(如 BP_DefaultContainer在编辑器中引用。

在 C++ 中使用: 容器需要绑定到 GameInstance 的 World 上下文才能获取注册表(通过 GetRegistry 辅助函数DefaultContainer.cpp:44-52。创建物品和查询都依赖注册表。

在 Blueprint 中使用: BP_DefaultContainer 是 UDefaultContainer 的蓝图子类无额外逻辑可在编辑器中作为资产创建。BP_InventoryComp 在编辑器中持有 BP_DefaultContainer 的引用,通过它对容器进行操作:

  • 调用 CreateItem 创建物品(需在 Authority 侧执行)。
  • 调用 GetItemViews 获取物品列表用于 UI 显示。
  • 调用 MoveItem 将物品移动到其他容器。

实现自定义容器: 继承 UDefaultContainer 并覆写虚方法即可创建自定义容器(如带槽位限制、堆叠功能的容器)。由于类标记了 Blueprintable也可以在 Blueprint 中继承。

当前实现的限制:

  • 存储使用 TArray 线性查找O(n)TODO 计划切换为 TMap 以提升性能DefaultContainer.h:32
  • 属性读写中的名称清理(点号→下划线)当前在 Internal_GetPropertyRaw / Internal_SetPropertyRaw 中处理TODO 计划提取到 NVI 层。

用例

  • Plugins/Item/Source/Item/Public/DefaultContainer.h:15-34 -- UDefaultContainer 类声明(继承 UObject + IItemContainer声明所有接口方法和 Items 成员)。
  • Plugins/Item/Source/Item/Private/DefaultContainer.cpp:44-52 -- GetRegistry 静态辅助函数,从 WorldContext 获取 UItemRegistrySubsystem。
  • Plugins/Item/Source/Item/Private/DefaultContainer.cpp:54-66 -- GetItemViews 实现:遍历 Items 并为每个物品调用 FItemViewFactory::CreateView。
  • Plugins/Item/Source/Item/Private/DefaultContainer.cpp:69-81 -- GetItemViewByID 实现。
  • Plugins/Item/Source/Item/Private/DefaultContainer.cpp:84-86 -- GetItemCount 实现。
  • Plugins/Item/Source/Item/Private/DefaultContainer.cpp:89-111 -- MoveItem 实现MoveTemp + RemoveAt + InjectPayload。
  • Plugins/Item/Source/Item/Private/DefaultContainer.cpp:113-127 -- CreateItem 实现:获取定义 → 工厂创建 → InjectPayload。
  • Plugins/Item/Source/Item/Private/DefaultContainer.cpp:129-134 -- InjectPayloadImpl 实现。
  • Plugins/Item/Source/Item/Private/DefaultContainer.cpp:137-187 -- Internal_GetPropertyRaw 实现(属性包读取 + 类型兼容性检查)。
  • Plugins/Item/Source/Item/Private/DefaultContainer.cpp:189-230 -- Internal_SetPropertyRaw 实现(属性包写入 + 类型兼容性检查)。
  • Document/Content/Blueprints/BP_DefaultContainer.md -- BP_DefaultContainer 是 UDefaultContainer 的 Blueprint 子类,在编辑器中作为可引用资产使用。
  • Document/Content/Blueprints/BP_InventoryComp.md -- BP_InventoryComp 持有 BP_DefaultContainer 引用并包装其操作。