# FItemPropertyEntry ## 基本信息 - **类型**: USTRUCT - **父类**: (无) - **源文件**: Plugins/Item/Source/Item/Public/ItemFactory.h - **模块**: Item ## 功能概述 面向设计师的结构体,将GameplayTag与类型无关的属性值选择器(FInstancedPropertyBag)配对。用于FItemDef::DefaultItemProps数组中,以定义默认动态属性。构造函数自动向ValuePicker添加一个类型为Bool、名称为"Property"的字段。 ## 设计用意 桥接GameplayTag(语义属性标识)与设计师编写的默认值。FInstancedPropertyBag提供类型安全的编辑器控件。"Property"子名称约定被ItemFactory::ConvertDefaultProps使用。 ## 职责范围 作为FItemDef中的声明条目。定义某个物品类型应具有哪些属性及其默认值。不直接在运行时使用(值会被复制到FItemInstance::ItemData中)。 ## 项目内依赖 (无项目内依赖) ## 对外接口 FItemPropertyEntry 是面向设计师的 USTRUCT,在 DataTable 编辑器中直接编辑。外部代码通常不直接构造此结构体,而是通过 FItemDef::DefaultItemProps 数组间接使用。 **可编辑字段:** - **PropertyTag** (FGameplayTag): 语义化的属性标识。例如 "Attribute.Health"、"Weapon.Damage" 等。在运行时,其 TagName 被用作物品属性包中的属性名称(点号会替换为下划线,参见 ItemFactory::ConvertDefaultProps 中的处理)。 - **ValuePicker** (FInstancedPropertyBag): 属性值选择器。构造函数自动添加一个名为 "Property"、类型为 Bool 的默认字段。设计师在编辑器中可将其类型改为 Int32、Float、FName、FString 等并设置默认值。 **运行时读取方式:** ItemFactory::ConvertDefaultProps 遍历 DefaultItemProps 数组,从每个 Entry 的 ValuePicker 中读取名为 "Property" 的属性描述和值,以 PropertyTag 的 TagName 为键写入 FItemInstance::ItemData。 **编辑器定制:** ItemEditor 模块(ItemEditorModule.cpp:23-26)注册了 FItemPropertyEntryCustomization 作为 "ItemPropertyEntry" 的自定义属性布局,提供增强的编辑器体验。 ## 使用方法 FItemPropertyEntry 在 DataTable 编辑器中作为 FItemDef::DefaultItemProps 数组的元素使用。 **DataTable 中的配置:** 设计师在物品的 FItemDef 行中添加 FItemPropertyEntry 元素: 1. 设置 PropertyTag(如 GameplayTag "Attribute.Health")。 2. 在 ValuePicker 中将 "Property" 字段的类型从默认 Bool 改为所需类型(Int32、Float、FName 等)并设置默认值。 **运行时转换:** ItemFactory::ConvertDefaultProps 是唯一读取 FItemPropertyEntry 的地方(ItemFactory.cpp:26-48): ```cpp void ItemFactory::ConvertDefaultProps( const TArray& DefaultProps, FInstancedPropertyBag& OutItemData) { for (const FItemPropertyEntry& Entry : DefaultProps) { const FPropertyBagPropertyDesc* SrcDesc = Entry.ValuePicker.FindPropertyDescByName(TEXT("Property")); if (!SrcDesc || !SrcDesc->CachedProperty) continue; // 从 ValuePicker 中读内存、复制到 OutItemData void* SrcPtr = SrcDesc->CachedProperty->ContainerPtrToValuePtr( const_cast(SrcMem)); const FName TargetName = FName(*Entry.PropertyTag.GetTagName() .ToString().Replace(TEXT("."), TEXT("_"))); OutItemData.AddProperty(TargetName, SrcDesc->ValueType, SrcDesc->ValueTypeObject); // ... 复制值到 OutItemData } } ``` 注意:PropertyTag 中的点号会被替换为下划线,因为属性包名称不允许点号。 **编辑器定制:** ItemEditor 模块注册了自定义属性布局(ItemEditorModule.cpp:23-26),使 FItemPropertyEntry 在编辑器中以定制方式展示,而非默认的结构体属性列表。 ## 用例 - `Plugins/Item/Source/Item/Public/ItemFactory.h:85-100` -- FItemPropertyEntry 结构体定义(PropertyTag、ValuePicker 字段 + 构造函数自动添加 "Property" Bool 字段)。 - `Plugins/Item/Source/Item/Public/ItemFactory.h:119` -- FItemDef::DefaultItemProps 声明为 TArray,是 FItemPropertyEntry 的唯一数组使用位置。 - `Plugins/Item/Source/Item/Private/ItemFactory.cpp:26-48` -- ConvertDefaultProps 是唯一读取 FItemPropertyEntry 的函数,遍历 DefaultProps 数组并将每个 Entry 的属性复制到 FInstancedPropertyBag。 - `Plugins/Item/Source/ItemEditor/Private/ItemEditorModule.cpp:23-26` -- 注册 FItemPropertyEntryCustomization 作为 "ItemPropertyEntry" 的自定义属性类型布局(编辑器模块)。 - `Plugins/Item/Source/ItemEditor/Private/ItemPropertyEntryCustomization.cpp` -- 编辑器定制实现,定制 FItemPropertyEntry 在 DataTable 编辑器中的显示方式。