步幅匹配
主要用于角色的循环移动动画,当角色完成起步后回进入循环移动动画,但角色的移动速度与动画的速度不匹配时依然会出现滑步的情况,所以我们通常会拿到角色的移动速度与动画的移动速度做比值来调整动画的播放速度从而使动画的移动与角色的速度相匹配。
除了动态调整循环动画的播放速度外,还需要调整角色的脚步步幅,一般来讲,当人的奔跑速度增加时,出了步频会增加外,步幅同样也会增加,所以为了防止角色的高速或低速情况下出现脚步鬼畜的情况,还需要对角色进行footik来调整步幅。
综上步幅匹配主要包括两部分:速度匹配和脚步ik
速度匹配

主要通过SetPlayrateToMatchSpeed来实现
1 | /** |
注释为:根据角色在游戏中的移动速度来设置动画的播放速度
- SequencePlayer:序列播放器,包含需要播放的动画序列
- SpeedToMatch:需要匹配的移动速度,通常为角色的地面移动速度
- PlayRateClamp:播放速度的上下限,默认为0.75到1.25
1 | FSequencePlayerReference UAnimDistanceMatchingLibrary::SetPlayrateToMatchSpeed(const FSequencePlayerReference& SequencePlayer, float SpeedToMatch, FVector2D PlayRateClamp) |
脚步IK
主要是通过跨步扭曲(StrideWarping)来实现。

在细节面板中展示了需要调整的选项,主要为添加需要进行匹配的脚步骨骼,StrideWarping节点本身需要传入开始混入的alpha值(skeleton control的强度)以及角色地面的移动速度(MatchSpeed)。
该节点定义在UAnimGraphNode_StrideWarping中,其中最主要的内容为声明的一个FAnimNode_StrideWarping类型的成员变量Node,在这个Node中定义了大多在细节面板中使用到的属性,同时还包括一些节点使用的初始化和更新方法。
初始化
其中初始化方法为:Initialize_AnyThread
1 | void FAnimNode_StrideWarping::Initialize_AnyThread(const FAnimationInitializeContext& Context) |
其中还有另一个初始化方法:InitializeBoneReferences,这个方法用于初始化我们在节点中写入的骨骼引用
更新
其中更新的方法为:EvaluateSkeletalControl_AnyThread,这是更新的主要方法,也是进行跨步扭曲的核心方法,接下来将对这个方法进行解析。
1 | void FAnimNode_StrideWarping::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseContext& Output, TArray<FBoneTransform>& OutBoneTransforms) |
更新流程:
- 获取实际的运动方向和运动速度
- 根据速度和方向调整脚步的位置
- 调整盆骨位置
- 根据盆骨的偏移和大腿的旋转限制脚步的位置
- 将调整后的骨骼数据添加到输出中并按照骨骼树进行排序
流程图
1 | flowchart TD |
- 本文作者: KongXinQing
- 本文链接: https://13114987559.github.io/2025/11/30/essay/步幅匹配/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!