UE5.8 Chooser 喂饭级专题

UE5.8 Chooser 专题(九):ProxyTable、嵌套 Chooser 和模块化内容

讲清 UProxyAsset、UProxyTable、LookupProxy、EvaluateProxyAsset、Nested Chooser、Evaluate Chooser,以及武器包、皮肤包、角色包如何覆盖选择结果。

总览

当项目变大,问题会从“怎么选结果”变成“同一个逻辑在不同角色、皮肤、武器包、DLC 下返回不同资产”。如果每个包复制一张 Chooser 表,维护会很痛。ProxyTable 和嵌套 Chooser 就是用来降低这种重复的。

UE5.8 Chooser 专题(九):ProxyTable、嵌套 Chooser 和模块化内容 配图
ProxyTable 让“我要什么”与“这个项目/皮肤/武器包给什么”解耦。

ProxyAsset 是“我要的东西”

UProxyAsset 可以理解成一个抽象请求:我要 Proxy.Combo.Light02.Montage,但具体给哪段 Montage,由当前 ProxyTable 决定。

它包含:

字段用途
Type期望输出类型
ResultTypeObject/Class
ContextData解析时需要的上下文
Guid稳定 Key

ProxyTable 是“这个内容包给的实现”

UProxyTable 里有多条 FProxyEntry,每条把 ProxyAsset 映射到一个 FObjectChooserBase 值。这个值可以是具体资产,也可以是 Evaluate Chooser、Nested Chooser、其它 ObjectChooser。

比如同一个 Proxy:

Proxy.Combo.Light02.Montage

不同表可以映射成:

DefaultHeroProxyTable -> AM_Default_Light02
SamuraiSkinProxyTable -> AM_Samurai_Light02
IceSwordProxyTable -> CHT_IceSword_Light02_Variants

LookupProxy 怎么用

动画节点或 Chooser Result 里可以使用 Lookup Proxy。运行时根据 Context 找到合适的 ProxyTable,再解析 ProxyAsset。蓝图侧有 EvaluateProxyAsset,也有 MakeLookupProxyMakeLookupProxyWithOverrideTable

初学可以先用显式 OverrideTable,项目成熟后再建立“当前角色/皮肤/武器拥有哪张 ProxyTable”的上下文规则。

嵌套 Chooser vs 独立 Chooser

方式适合
Nested Chooser同一个资产里小范围分支,方便一起编辑
Evaluate Chooser可复用的大分支,多个系统共享
ProxyTable内容包覆盖、皮肤/武器/角色变体

不要用 ProxyTable 替代所有表。ProxyTable 解决间接映射和覆盖,Chooser 解决上下文决策。

使用案例:玩家连招 + 皮肤动画覆盖

战斗流程:

  1. Gameplay Chooser 选中 Move.Sword.Light02
  2. MoveData 里引用一个 ProxyAsset:Proxy.Move.Light02.Montage
  3. 当前角色皮肤提供 SkinProxyTable
  4. LookupProxy 解析出 AM_Samurai_Light02
  5. 如果皮肤没有覆盖,继承表回退到默认 Montage。

玩家连招档案不需要关心皮肤资产;皮肤包也不需要修改玩家的连招配置。

使用案例:Game Feature 武器包

一个武器包可以带自己的 ProxyTable:

WeaponPack_IceSword
  PT_IceSword_ComboAssets
  CHT_IceSword_LightVariants
  DA_Move_IceSpin
  AM_IceSpin_A
  AM_IceSpin_B

Game Feature 激活后,把这张 ProxyTable 加入角色或装备上下文。Chooser 表仍然请求同一个 ProxyAsset,但解析结果变成冰剑包里的资产。

架构分析

Proxy 的价值是解耦“语义”和“实现”。语义是 Light02 Montage,实现是某个资产或某张子表。大型项目里语义最好稳定,内容包可以替换实现。这样玩家档案、技能表、动画表、皮肤包不需要互相硬引用。

常见坑

  • ProxyAsset 太细,项目里出现成百上千个难维护 Key。
  • ProxyTable 继承链太深,调试不知道最终来自哪张表。
  • 用 ProxyTable 做条件判断,结果表和选择职责混乱。
  • Proxy 返回类型和调用方期望不一致。
  • Game Feature 停用后还持有 ProxyTable 强引用,内容包卸不干净。

源码依据

UProxyAsset 声明 Type、ResultType、ContextData 和 Guid。UProxyTable 运行时有 RuntimeValues,编辑器期有 EntriesInheritEntriesFromFProxyEntry 的 ValueStruct 是 FObjectChooserBase,因此 Proxy 可以解析到具体对象,也可以继续 Evaluate Chooser。UProxyTableFunctionLibrary 提供 EvaluateProxyAssetMakeLookupProxy 和带 OverrideTable 的版本。

源码路径索引

  • Engine/Plugins/Chooser/Source/ProxyTable/Public/ProxyAsset.h
  • Engine/Plugins/Chooser/Source/ProxyTable/Public/ProxyTable.h
  • Engine/Plugins/Chooser/Source/ProxyTable/Public/ProxyTableFunctionLibrary.h
  • Engine/Plugins/Chooser/Source/ProxyTable/Internal/LookupProxy.h
  • Engine/Plugins/Chooser/Source/Chooser/Public/Chooser.h
  • Engine/Plugins/Chooser/Source/Chooser/Private/Chooser.cpp