init
This commit is contained in:
87
Plugins/Item/UItemTracer.md
Normal file
87
Plugins/Item/UItemTracer.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# UItemTracer
|
||||
|
||||
## 基本信息
|
||||
- **类型**: UCLASS(BlueprintType)
|
||||
- **父类**: UObject
|
||||
- **源文件**: Plugins/Item/Source/Item/Public/ItemFactory.h
|
||||
- **模块**: Item
|
||||
|
||||
## 功能概述
|
||||
嵌入在FItemInstance属性包中的轻量级追踪对象。存储当前容器位置,并暴露OnItemMoved多播委托。提供Blueprint查询函数用于查询物品位置。
|
||||
|
||||
## 设计用意
|
||||
解决"物品在哪"的问题,无需全局注册表。存在于物品的属性包中(随物品迁移)。由IItemContainer::InjectPayload NVI包装自动更新。OnItemMoved委托使UI/任务系统能响应物品移动事件。
|
||||
|
||||
## 职责范围
|
||||
追踪和广播物品位置变化。由InjectPayload在插入时更新位置。UPROPERTY位置使用TObjectPtr(非强引用),避免泄漏。
|
||||
|
||||
## 项目内依赖
|
||||
(无项目内依赖)
|
||||
|
||||
## 对外接口
|
||||
UItemTracer 是 BlueprintType,嵌入在物品的属性包中(键名为 Internal_ItemTracer),随物品在容器间迁移。外部代码通过属性包获取 Tracer 引用后,可调用以下接口:
|
||||
|
||||
**Blueprint 可调用:**
|
||||
- **GetItemLocation()** (BlueprintPure, BlueprintAuthorityOnly) → const UObject*: 返回物品当前所在的 UObject 位置。在 InjectPayload NVI 中,此位置被设置为容器对象(Cast<UObject>(this))。返回值可能为空(物品尚未被注入任何容器)。
|
||||
- **FindActorInOuterChain()** (BlueprintPure, BlueprintAuthorityOnly) → const AActor*: 从物品位置出发,沿 Outer 链向上查找第一个 AActor。如果物品容器是 Actor 的组件/子对象,此方法可追溯到所属 Actor。找不到则返回 nullptr。
|
||||
|
||||
**委托:**
|
||||
- **OnItemMoved** (FOnItemMoved, BlueprintAssignable): DYNAMIC_MULTICAST_DELEGATE_OneParam 类型的动态多播委托。在 IItemContainer::InjectPayload 中被广播(参数为 Tracer 自身)。UI 或任务系统可绑定此委托以响应物品移动事件。
|
||||
|
||||
**C++ 专用:**
|
||||
- **SetItemLocation(UObject*)**: 设置 Tracer 的位置引用。不暴露到 Blueprint。仅由 IItemContainer::InjectPayload NVI 调用(ItemContainer.cpp:59),确保位置更新与移动广播的原子性。
|
||||
|
||||
## 使用方法
|
||||
UItemTracer 由 ItemFactory 创建并嵌入物品属性包,由 InjectPayload 自动更新。外部代码(如 Blueprint UI)从物品属性包中获取 Tracer 引用后使用。
|
||||
|
||||
**创建(ItemFactory.cpp:17-22):**
|
||||
```cpp
|
||||
if (ItemDef.bHasTracer)
|
||||
{
|
||||
Instance->ItemData.AddProperty(UInternalItemProperty::ItemTracer(),
|
||||
EPropertyBagPropertyType::Object, UItemTracer::StaticClass());
|
||||
UItemTracer* NewTracer = NewObject<UItemTracer>();
|
||||
Instance->ItemData.SetValueObject(
|
||||
UInternalItemProperty::ItemTracer(), NewTracer);
|
||||
}
|
||||
```
|
||||
|
||||
**位置更新(ItemContainer.cpp:45-67 - InjectPayload NVI):**
|
||||
```cpp
|
||||
void IItemContainer::InjectPayload(TUniquePtr<struct FItemInstance> Payload)
|
||||
{
|
||||
if (!Payload.IsValid()) return;
|
||||
const FName PropName = UInternalItemProperty::ItemTracer();
|
||||
if (const FPropertyBagPropertyDesc* Desc =
|
||||
Payload->ItemData.FindPropertyDescByName(PropName))
|
||||
{
|
||||
if (UObject* SelfAsObject = Cast<UObject>(this))
|
||||
{
|
||||
TValueOrError<UObject*, EPropertyBagResult> Result =
|
||||
Payload->ItemData.GetValueObject(PropName);
|
||||
if (Result.HasValue())
|
||||
{
|
||||
if (UItemTracer* Tracer = Cast<UItemTracer>(Result.GetValue()))
|
||||
{
|
||||
Tracer->SetItemLocation(SelfAsObject);
|
||||
Tracer->OnItemMoved.Broadcast(Tracer); // 广播移动事件
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
InjectPayloadImpl(MoveTemp(Payload));
|
||||
}
|
||||
```
|
||||
|
||||
**在 Blueprint 中绑定移动事件:**
|
||||
UI 或任务系统通过获取物品属性包中的 Internal_ItemTracer 对象,绑定其 OnItemMoved 委托来响应物品移动。当容器调用 InjectPayload 时,委托被广播,绑定的监听方收到通知。
|
||||
|
||||
**查询位置:**
|
||||
在 Blueprint 中调用 GetItemLocation 获取物品当前所在 UObject,或调用 FindActorInOuterChain 追溯到所属 Actor。
|
||||
|
||||
## 用例
|
||||
- `Plugins/Item/Source/Item/Public/ItemFactory.h:27` -- FOnItemMoved 委托类型声明(DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam)。
|
||||
- `Plugins/Item/Source/Item/Public/ItemFactory.h:29-57` -- UItemTracer 类定义(OnItemMoved 成员 + GetItemLocation / FindActorInOuterChain / SetItemLocation 方法)。
|
||||
- `Plugins/Item/Source/Item/Private/ItemFactory.cpp:17-22` -- CreateItemInstance 中当 bHasTracer 为 true 时创建 UItemTracer 并添加到属性包。
|
||||
- `Plugins/Item/Source/Item/Private/ItemContainer.cpp:49` -- InjectPayload NVI 中通过 UInternalItemProperty::ItemTracer() 键名查找 Tracer。
|
||||
- `Plugins/Item/Source/Item/Private/ItemContainer.cpp:57-60` -- InjectPayload 中 Cast 到 UItemTracer,调用 SetItemLocation 更新位置,Broadcast OnItemMoved 通知监听方。
|
||||
Reference in New Issue
Block a user