Use Orientation Warping With Sequence Evaluator

2.7k 词

问题介绍

仿制 Lyra 的运动系统时,在 Start 与 Stop 动画处,使用 Orientation Warping 失效;而在 Cycle Layer 使用正常。

具体表现为:

  • 角色的骨骼未跟随 Locomotion Angle 发生相应扭曲,例如当玩家向右后方前进时,角色骨骼仍然朝后。
  • 通过 debug 发现,角色没有 Root Motion


问题解决流程

动画素材检查

起初,我怀疑在重定向动画前,原素材未启用 Root Motion 或启用了 Force Root Lock

随后我尝试重新重定向动画,再次设置素材,没有任何变化。


Orientation Warping 节点

Orientation Warping 介绍

Orientation Warping 是 Unreal Engine 动画蓝图中的一种 姿态扭曲(Pose Warping)技术,它可以根据角色的移动方向动态调整骨骼的朝向,使原本只适用于向前奔跑的动画也能自然地应用于各个方向。

开发者就可以通过四向前进动画实现 360° 移动时的自然身体旋转。

在传统动画系统中,如果角色需要在不同方向上奔跑,通常需要为每个方向单独制作动画。但使用 Orientation Warping 后,可以在运行时根据角度对角色骨骼(通常是 Spine)进行扭曲,以适应移动方向。

在 Orientation Warping 中,无论采用哪种模式,都将最终使用一个叫 Orientation Angle(float) 的数据,作为调整骨骼朝向的依据。

根据不同的 Mode,Orientation Angle 有不同的获取来源。


Mode

Orientation Warping 有两种 Mode:

1. Manual Mode

在该模式下,用户需要直接提供已经计算完成的 Orientation Angle(float)。

2. Graph Mode

在该模式下,用户可以提供两类信息:

  • Locomotion DirectionFVector 类型的数据,是 Character 在世界坐标系下的移动方向;该节点会根据该数据自动计算 Locomotion Angle
  • Locomotion Anglefloat 类型的数据,一般由 Character 的移动方向与 Actor Rotation 计算得到,可以使用 Calculate Direction 来计算。

两个数据,提供一个即可;当节点得到 Locomotion Angle 后,会计算与 Root Motion Angle 的差值,得到 Orientation Angle,调整骨骼。


修改输入变量

我使用了 Graph Mode

我怀疑我错误地计算了 Locomotion Angle;因为在发现这个问题之前,我在实现转身模块,该模块会在 Idle 状态积累 CharacterRotation 旋转角度,并通过 Rotate Root Bone 旋转 Mesh;在运动状态下,通过弹簧插值,恢复角色朝向。

Start 状态有可能处在恢复状态,此时 LocomotionAngle 会与实际方向错位。

所以需要更新 Locomotion Angle 的数值,应减去 Root Yaw Offset

我以为是这一步出错了,检查了接口、实时数据,也取消了 Offset,均无效。

随后我开始尝试计算 Locomotion Direction,让节点自己算 Angle,无效。

随后我改为 Manual Mode

并计算 Locomotion Angle 与 Root Motion Angle 的差值,在 Cycle 正常,在 Start / Stop 还是无效。

因为 Root Motion 始终为 ZeroVector。这说明动画实际上并没有发生根位移。


单独测试动画

我单独创建了新的角色蓝图与动画蓝图,在动画蓝图部分只设置 Start 动画与固定 Locomotion Angle 的 Orientation Warping,结果显示该情况下,Orientation Warping 运行正常。

这再一次说明,动画素材本身没有问题,还是蓝图的问题。

我回顾了,该条件与 Start Layer 的不同,似乎只有 Sequence Evaluator 与 Sequence Player 有区别。


Sequence Evaluator 与 Sequence Player

Sequence Player

Sequence Player 节点是动画蓝图中最常用的动画播放节点之一。它会从头开始以设定的播放速率连续播放一个指定的动画资产(Anim Sequence),并随着动画时间推移自动推进动画状态。

主要特点:

  • 支持循环(Looping)播放;
  • 支持播放速率控制;
  • 支持动画通知(Anim Notifies)触发;
  • 与状态机(State Machine)结合使用时非常常见。

适用场景:

  • 连续的移动、攻击等动作;
  • 角色的正常动画循环控制。

Sequence Evaluator

Sequence Evaluator 节点用于评估动画在某一个具体时间点的姿态(Pose),而不会播放动画。

主要特点:

  • 仅根据设置的 “Explicit Time” 参数评估并输出当前姿态;
  • 不自动推进时间(除非手动设置 Explicit Time);
  • 可选 “Teleport to Explicit Time” 用于跳过插值、瞬间跳转到该帧;
  • 常用于姿态混合、特定帧采样或基于时间控制的系统。

适用场景:

  • 精确控制动画采样(如根骨提取);
  • 自定义 blend pose 系统;
  • 动作采样器(Pose Sampler)或时间轴驱动的动画。

结果

事实上,Cycle Layer 与 Start / Stop Layer 的区别,也有使用 Sequence Evaluator 与 Sequence Player 的区别。

Cycle Layer,使用的是 Sequence Player,因为我们通过 Stride Warping 与合理的 Movement 参数设置,就不会出现滑步的情况;在 Start / Stop Layer,由于速度变化快,且有一段时间速度很小,所以需要进行更精确的控制,采用的方案是设置 Distance Curve,实时根据角色的移动距离,匹配动画序列的播放时间,所以使用 Sequence Evaluator,该节点能按帧控制动画。

我仔细查看了 Sequence Evaluator,发现了一个不太了解的设置:Teleport to Explicit Time

该设置解释如下:

总结起来:是否瞬间跳转到指定的时间,而不是通过时间插值前进

例如启用时,当下一帧动画应该从第 15 帧转到第 20 帧时,是否需要插值。

默认启用的情况下,动画不进行插值,而是离散地跳转。

它中断了动画的“时间连续性”和运动趋势。

所以很有可能是该选项导致的,我取消了该选项后,表现恢复正常。


PS:其实这一部分内容我之前是做过一次的,回看当时的仓库居然鬼使神差地取消了该属性,我想当时第一次做,看得仔细,便避免了这个错误,现在第二次做,以为熟练了,结果忽视了这个问题。

留言