总览
Chooser 最早很容易被动画团队喜欢上:不同速度、武器、朝向、地面状态、镜像状态下要选不同动画,写成 AnimBP 分支会很膨胀,写成表就清楚很多。
Chooser Player 节点做什么
FAnimNode_ChooserPlayer 继承 FAnimNode_BlendStack_Standalone,它会在动画更新时 Evaluate 一个 FObjectChooserBase,选出 UAnimationAsset,再用 BlendStack 播放。
它内置几个关键概念:
| 字段 | 用途 |
|---|---|
EvaluationFrequency | 什么时候重新 Evaluate:初次、变 relevant、循环、每帧 |
Chooser | Evaluate Chooser 或 Lookup Proxy |
DefaultSettings | 默认播放设置 |
FChooserPlayerSettings | 运行时可被 Chooser 输出列改写的设置 |
bStartFromMatchingPose | 配合 Pose Search 从匹配姿态开始 |
EvaluationFrequency 怎么选
| 模式 | 适合 |
|---|---|
| OnInitialUpdate | 一进节点选一次,不希望频繁换 |
| OnBecomeRelevant | 状态重新 relevant 时选,常用 |
| OnLoop | 动画循环边界重新选,适合 idle/locomotion 变体 |
| OnUpdate | 每次更新都选,灵活但要谨慎 |
连招 Montage 一般不靠 Chooser Player 每帧选;更常见是在 Gameplay 侧选 Ability/Montage,然后 AnimBP 播放。Locomotion/Idle/Start/Stop 变体更适合 Chooser Player。
FChooserPlayerSettings 能输出什么
FChooserPlayerSettings 包含镜像、开始时间、强制循环、播放速率、曲线覆盖、BlendTime、BlendProfile、BlendOption、Inertial Blend 等。Chooser 表可以通过输出列改它。
例如:
| 条件 | Result | 输出 |
|---|---|---|
| Sword + Speed 0 | Idle_Sword_A | Mirror=false, BlendTime=0.2 |
| Sword + Speed 0 | Idle_Sword_B | Mirror=true, BlendTime=0.25 |
| HeavyWeapon + Start | Start_Heavy | PlaybackRate=0.9 |
Pose Search 配合
当 bStartFromMatchingPose 打开且 PoseSearch 可用时,Chooser Player 会先收集 Chooser 选出的候选资产,再交给 Pose Search Provider 找最匹配的开始点。这适合从多个候选动画里选一段姿态连续性更好的动画。
这时 Chooser 负责缩小候选集,Pose Search 负责在候选集里找姿态最优解。
UAF 集成
UE5.8 的 UAFChooser 插件提供 UAF 侧桥接。UUAFAnimChooserTable 是 UAF 特定的 Chooser Table 子类;RigUnit_EvaluateChooser 会构造 FChooserEvaluationContext,把 ControlRig、ContextObject 或 UAF AssetInstance 加进去,再调用 UChooserTable::EvaluateChooser。
如果你已经在用 UAF,把 Chooser 当成“动画图/动画资产选择策略”会比较自然。UAF 负责图和执行,Chooser 负责根据上下文选哪一个。
Gameplay Chooser 和 Animation Chooser 分工
同一个动作不要重复判两遍合法性。推荐:
Gameplay Chooser: 选择下一段技能或 MoveData
GAS: 判断能不能激活并执行
Animation Chooser: 在技能已确定后,选择表现变体或起始姿态
比如 Gameplay Chooser 选中了 Move.Sword.Light02。动画侧再根据速度、朝向、镜像、武器皮肤,选择 AM_Sword_Light02_A 或 AM_Sword_Light02_B。
使用案例:玩家编辑技能连招 + 动画变体
玩家把轻攻击第二槽设为“旋斩”。战斗中:
- Gameplay Chooser 选中
DA_Move_SwordSpin。 - GAS 激活
GA_SwordSpin。 - Ability 把
MoveTag=Skill.Sword.Spin、WeaponTag=Weapon.Sword、bIsMirrored传给 AnimInstance。 - Animation Chooser 选择具体 Montage 或 Sequence。
- Output 写 BlendTime、StartTime、Mirror 和 CameraCue。
这样玩家编辑的是技能语义,动画团队仍然能按上下文扩展表现。
架构分析
动画 Chooser 很容易被滥用成 Gameplay 判断。记住:动画可以拒绝播放空资产,但不应该决定技能是否合法。技能是否合法是 GAS/服务器权威逻辑。动画表只决定“合法动作如何表现得更好”。
常见坑
- Chooser Player 用 OnUpdate 选重表,动画线程压力变大。
- 动画表里绑定 Gameplay 对象深字段,AnyThread 场景不安全。
- Gameplay 和 Animation 两张表规则不一致,一个认为能出招,一个找不到动画。
- Pose Search 候选资产太多,Chooser 没起到缩小候选作用。
- UAF 里忘记传 ContextObject,表里对象参数全部为空。
源码依据
FAnimNode_ChooserPlayer::ChooseAsset 构造 FChooserEvaluationContext,加入 AnimInstance 和 FChooserPlayerSettings,再调用 FObjectChooserBase::ChooseObject。节点支持 EChooserEvaluationFrequency、BlendStack 播放、曲线覆盖、镜像和 Pose Search。UAFChooser 的 RigUnit_EvaluateChooser 同样构造 Context 并调用 UChooserTable::EvaluateChooser。
源码路径索引
Engine/Plugins/Chooser/Source/Chooser/Internal/AnimNode_ChooserPlayer.hEngine/Plugins/Chooser/Source/Chooser/Private/AnimNode_ChooserPlayer.cppEngine/Plugins/Chooser/Source/Chooser/Public/ChooserTypes.hEngine/Plugins/Chooser/Source/ChooserUncooked/Public/AnimGraphNode_ChooserPlayer.hEngine/Plugins/Experimental/UAF/UAFChooser/Source/UAFChooser/Public/UAFAnimChooser.hEngine/Plugins/Experimental/UAF/UAFChooser/Source/UAFChooser/Private/RigUnit_EvaluateChooser.cpp