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

101 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# FItemInstance
## 基本信息
- **类型**: USTRUCT
- **父类**: (无)
- **源文件**: Plugins/Item/Source/Item/Public/ItemFactory.h
- **模块**: Item
## 功能概述
单个运行时物品的内部重量级表示。包含唯一GUID、类型键以及FInstancedPropertyBag中的动态属性。由容器通过TUniquePtr独占拥有。具有friend class ItemFactory用于受控构造。
## 设计用意
物品的运行时真值源。刻意不作为BlueprintType公开。TUniquePtr所有权确保清晰的单拥有者语义。FInstancedPropertyBag允许每个物品拥有任意的动态属性。友元控制构造防止产生孤立物品。
## 职责范围
持有单个物品实例的所有运行时状态。通过TUniquePtr在容器间经由InjectPayload传递。不向容器/工厂外部暴露修改接口。
## 项目内依赖
(无项目内依赖)
## 对外接口
FItemInstance 是内部使用的 USTRUCT非 BlueprintType不作为公共 API 直接暴露给外部代码。其字段均标记为 UPROPERTY()(无 BlueprintReadOnly供容器和工厂内部访问。
外部调用方不应直接创建或修改 FItemInstance。与 FItemInstance 交互的唯一入口是通过以下间接途径:
- **创建**: 通过 UDefaultContainer::CreateItem或 IItemContainer::CreateItem内部调用 ItemFactory::CreateItemInstance。
- **查询**: 通过 IItemContainer::GetItemViews() 获取 FItemView 快照,而非直接访问 FItemInstance。
- **属性读写**: 通过 IItemContainer::GetItemProperty / SetItemProperty而非直接操作 FItemInstance::ItemData。
内部字段供 ItemFactory 和容器实现者使用:
- **ItemID** (FGuid): 物品唯一标识,由工厂在创建时通过 FGuid::NewGuid() 生成。
- **ItemType** (FName): 物品类型名称,对应 DataTable 中的行名,用于在注册表中查找 FItemDef。
- **ItemData** (FInstancedPropertyBag): 物品的动态属性包。包含从 FItemDef::DefaultItemProps 转换来的属性,以及可选的 OverrideProps 合并值。当 bHasTracer 为 true 时还包含 Internal_ItemTracer 键。
所有权模型FItemInstance 只能通过 TUniquePtr 持有,禁止复制(拷贝构造 / 赋值运算符保留但标记为 default实际应避免使用。移动语义开放移动构造和移动赋值 = default支持在容器间转移所有权。
## 使用方法
FItemInstance 不直接被外部代码创建或操作。外部代码通过容器接口间接交互。
**创建(仅通过 ItemFactory**
```cpp
// ItemFactory.cpp:6-24
TUniquePtr<FItemInstance> ItemFactory::CreateItemInstance(
const FItemDef& ItemDef, FName ItemType,
const FInstancedPropertyBag* OverrideProps)
{
TUniquePtr<FItemInstance> Instance = MakeUnique<FItemInstance>();
Instance->ItemID = FGuid::NewGuid();
Instance->ItemType = ItemType;
ConvertDefaultProps(ItemDef.DefaultItemProps, Instance->ItemData);
if (OverrideProps)
MergePropertyBag(*OverrideProps, Instance->ItemData);
if (ItemDef.bHasTracer)
{
Instance->ItemData.AddProperty(UInternalItemProperty::ItemTracer(),
EPropertyBagPropertyType::Object, UItemTracer::StaticClass());
UItemTracer* NewTracer = NewObject<UItemTracer>();
Instance->ItemData.SetValueObject(
UInternalItemProperty::ItemTracer(), NewTracer);
}
return Instance;
}
```
**存储(由 UDefaultContainer 管理):**
```cpp
// DefaultContainer.h:33
TArray<TUniquePtr<struct FItemInstance>> Items;
// DefaultContainer.cpp:129-135 - 注入存储
void UDefaultContainer::InjectPayloadImpl(TUniquePtr<FItemInstance> Payload)
{
if (Payload.IsValid())
Items.Add(MoveTemp(Payload));
}
```
**读取属性(由容器内部处理):**
容器通过 ItemData 读取属性值和描述符。例如 DefaultContainer.cpp:137-187 的 Internal_GetPropertyRaw 中:
```cpp
const FPropertyBagPropertyDesc* Desc =
Bag->FindPropertyDescByName(FixedName);
void* BagMemory = FoundItem->ItemData.GetMutableValue().GetMemory();
void* SourceAddr = Desc->CachedProperty->ContainerPtrToValuePtr<void>(BagMemory);
```
**在所有容器间转移所有权:**
通过 MoveTemp + InjectPayload 组合操作。物品的 TUniquePtr 所有权从源容器移至目标容器DefaultContainer.cpp:104-108
## 用例
- `Plugins/Item/Source/Item/Public/ItemFactory.h:60-82` -- FItemInstance 结构体定义ItemID、ItemType、ItemData 三个字段 + 友元声明 + 构造/移动/拷贝控制)。
- `Plugins/Item/Source/Item/Private/ItemFactory.cpp:6-24` -- ItemFactory::CreateItemInstance 创建 FItemInstance 的唯一入口MakeUnique + 填充字段 + 属性转换 + Tracer 创建)。
- `Plugins/Item/Source/Item/Private/DefaultContainer.cpp:60-64` -- GetItemViews 遍历 Items 数组中的 TUniquePtr<FItemInstance> 并解引用传递给 FItemViewFactory。
- `Plugins/Item/Source/Item/Private/DefaultContainer.cpp:73-78` -- GetItemViewByID 按 ID 匹配 Items 中的 FItemInstance 指针。
- `Plugins/Item/Source/Item/Private/DefaultContainer.cpp:96-108` -- MoveItem 通过 MoveTemp 转移 FItemInstance 所有权,从源数组 RemoveAt 后注入目标容器。
- `Plugins/Item/Source/Item/Private/DefaultContainer.cpp:121-124` -- CreateItem 接收工厂返回的 TUniquePtr<FItemInstance> 并注入自身。
- `Plugins/Item/Source/Item/Private/DefaultContainer.cpp:129-134` -- InjectPayloadImpl 接收 TUniquePtr<FItemInstance> 并 Add 到 Items 数组。
- `Plugins/Item/Source/Item/Private/DefaultContainer.cpp:140-186` -- Internal_GetPropertyRaw 从 FoundItem->ItemData 中按属性名称读取值。
- `Plugins/Item/Source/Item/Private/ItemContainer.cpp:45-67` -- InjectPayload NVI 从 Payload->ItemData 中读取 Tracer 并更新位置。
- `Plugins/Item/Source/Item/Private/ItemViewFactory.cpp:11-19` -- PopulateCommon 从 Instance.ItemID / Instance.ItemType 读取字段填入 FItemView。