在UE5中,预测脚步IK实现-PredictFootIK
- 作者:admin
- /
- 时间:2小时前
- /
- 浏览:17 次
- /
- 分类:厚积薄发
【USparkle专栏】如果你深怀绝技,爱“搞点研究”,乐于分享也博采众长,我们期待你的加入,让智慧的火花碰撞交织,让知识的传递生生不息!
一、前言与简述
1. 前言
“最终效果可见文尾”。
此篇文章主要是记录开发过程中的一些细节与踩坑,基础动画框架是复刻的ALS,技术方案来自刺客信条基于预测的FootIK。
自己实现过程中也参考了其他大佬的文章(链接放末尾),实现的方法可能存在很多问题,写法也不是很优雅。文章中一些步骤为制作过程记录,也有补录,可能存在顺序或制作内容和正常顺序有差别,有一些细节或者坑可能忘记了,还请见谅。
2. 简述

基于预测的FootIK通过预测角色的落点来计算即将行走的路径,从而通过IK更改脚步和盆骨来适配地形,相较于传统IK会更加灵活(当然也更复杂)。
总体步骤为:
- 准备脚步数据
- 预测脚步落点
- 计算Pelvis数据
- 计算脚步路径
- 计算脚步数据
- 应用数据
二、准备数据与预测
1. 数据准备
在此阶段我们需要在动作中添加一个曲线,通过这个曲线上的时间来告诉我们脚步还有多久会落下,但正如育碧所言:“Absolutely must be automated”,所以我使用的是UE的AnimationModifier来自动的生成曲线,在其中通过对动画信息进行采样,获取当前帧信息。

之后通过获取到的Foot高度(可以更加细致,比如加上脚尖,甚至旋转等)来判断是否为关键点,如果是就记录下来。这里我还开放了FootName和Height的阈值作为参数。
这里获取脚步位置没有直接的函数,需要GetAnimPosAtTime之后去GetBonePose获取,然后根据获取到的脚步落下与脚步抬起关键点来连成曲线。
这里找到落点其实很简单,但生成曲线还比较麻烦,要注意开始点和结束点的连贯,以及曲线应该改成线性。最后就可以得到自动生成的曲线。

2. 脚步预测
在开始之前我创了一个结构体,往里加入很多参数避免之后修改一次就要改函数输入,又要加一堆参数。

在PreDictFootLocation中,思路是通过我们之前生成的脚步落地曲线以及角色的移动速度来获取落点(除去黑框的内容)。

而其中黑框主要是来解决脚步相对位置的问题。
如果你只是一个动作,可以直接写死相对位置,但如果要应用到游戏中的各个动作,它的脚步相对位置会有差距,这个时候我最先想的是:那我实时计算脚步的位置不就好了?
但脚步会有在后面和在前面,比如落脚的时候不会跟随角色移动,如果用实时位置,那么预测的位置必定很不准确。所以我采取的做法是在落地时记录相对位置,然后用黑框中进行计算。
而这其中的脚步落下是通过一个参数记录上一帧脚步是否落下,如果上一帧落下则更新,同理也可以得到脚步抬起时刻来获取信息。
例如在脚落下时记录脚相对位置,脚步开始位置设为当前脚步位置,上一次的结束位置等。这就是脚步开始位置,而结束位置是通过我们的BoxTrace实时得到的。
这里其实还有个小问题,就是预测的落点会有误差。在移动的时候会逐渐非常缓慢向角色靠近(可看下方视频慢放时)。这个虽然影响不大,但在脚步离台子非常近的时候会有抖动,目前这个问题找了动作、曲线、角色都没找到原因。就先不管了,最后画一画DebugShape就可以得到如下效果:
三、计算Pelvis数据
1. Pelvis起始点与终点
来到Pelvis的计算,首先要获取两脚间的起始点位置(绿线)作为Pelvis计算的起始点和终止点:

这个开始点和结束点的切换是在脚步交错时进行,所以我就直接根据脚步的Y值谁更靠前来决定,当和上一帧不同时则为切换,这个时候更新双脚位置。

注意结束点要在脚落地时一直更新,因为我们之前提到了会有误差,那个落点会一点点向角色靠近,如果只取那一帧的会对不上,所以在脚落地时Pelvis的落点也要一直更新。
这里有些动作会在短时间内交叉两次(比如ALS的冲刺)导致错误,所以还需要对切换加上一个很小的冷却时间,这个时候我们就可以得到下面视频的绿色曲线:
可以看到,我们在上下坡时Pelvis会随着碰撞体一直运动,但我们的预期是在上坡落脚时上升,和在下坡时边下坡边下降,所以首先要固定住Pelvis,之后再去加位移。
2. 上下坡
这里固定Pelvis我之前尝试过使用PelvisOffset去做,但是不知道是不是因为更新时机或顺序的问题,会延迟一帧,导致强烈抖动。
所以我最后采取的做法是直接Set角色保持Mesh的高度一直在StartPos处(黑框后面会说)。

此时就可以得到如下效果,可以看到我们角色是一直和开始点保持同样高度:
之后就是处理我们的上坡和下坡的逻辑(平地可视为上坡下坡)来计算Pelvis Addtive Offset Target。
上坡是要落地后采样,并且在结束后Mesh会抬升到新的开始点,所以Addtive要变为0,不然会在原有基础再高一截。而且下坡则是要在没有落地时采样落地,因为脚步落地后,脚步可能还未交叉,开始点还未更新,所以要保持Addtive未最后一个点,不然在交叉腿时会抖。

现在我们知道了怎么计算,但是如何采样呢?这里提前计算了StartFootRate和EndFootRate(Rate这里我代指比例)。
之前尝试过用曲线值来采样,但是一直不准确,还有些其他问题就没用曲线。
先说EndFoot,它是用在下坡时采样。在脚步交错时,EndFoot其实已经抬起后运动了一段距离(下图左脚),通过记录交错时脚步到交错时脚步位置和到最后点位置(XY方向上的长度)的比例来设置。


对于StartFootRate则比较简单,因为交错时StartFoot是落地的,所以直接看到StartPos的距离和End的距离即可。
最后将Mesh偏移哪里的Addtive加上去,就有下面的效果:
四、计算Foot路径数据
1. FootPath
计算过程很简单,就是从一直脚的开始和结束点作为初始点。
从开始到结束和结束到开始分别打射线,在检测到碰撞后再从顶上向下打BoxTrace找到碰撞点,这个时候把两个新的点作为下一次的开始点和结束点,直接没有发生碰撞,或者达到迭代次数上限,最后将所有点数依次组合起来 从开始点到结束点放进数组中。

得到这些点后,我们还需要准备一个数据,用于之后采样。
我们还需要知道脚步到何时需要这个点,此处曾尝试过预测曲线,但不精准有问题,最后采用的还是和上面Pelvis采样相同方法。
通过记录每个点到开始点的距离比例,记录下来,这样开始点是0,结束点是1,中间点介于0-1,最后就得到了FootPath记录点位世界坐标的数组和一个Foot Curve Vars的数组。

2. FootPath采样
计算完上述之后,我们需要知道角色当前取哪个点。
首先要确定角色的脚步位于哪两个路径点之间,就需要根据角色脚步到这一段路径的起始点和终点的距离比例来插值获取位置信息。
可以看到下图中白色小球就是我们采样的位置:
五、应用Foot与更正IK问题
1. Foot
计对于Foot我们仍然要从脚当前位置向上和向下去打一条射线,通过碰撞点得到Trace的脚步位置。
将这个Trace的位置和我们的当前路径采样位置做比较,取更高的那一个,这样就能保证脚步不穿墙。
得到IK位置之后就需要计算偏移,这里要和地面的距离来算而不是脚步位置,否则脚步的动画运动细节会被IK覆盖掉。
最后对位置和旋转平滑一下即可,这个时候如果你运行起来,可以看到平地是基本正常,但上下坡你会发现很奇怪:
所以我们需要在之后进行Pelvis的更正。
2. Pelvis更正
上坡时脚被压着很难受,是因为我们的Pelvis目前严格跟随我们的预测落点,所以在上坡时脚开始抬升前,它的高度并不会动(甚至坡度很抖会穿进去)。
所以我们需要给它一些额外的高度。
我采取的策略是让其不低于最低脚的偏移,这样上坡时就会正常。但是,如果当运动速度比较快,前脚抬的比较高也会有诡异情况,所以我们的Pelvis还要根据前脚的角度来进行一定的偏移,但是如果根据更高的脚来进行,对平地和下坡有一定影响,所以要进行一些处理。

3. 其他脚步问题修复
你以为这样就完美了吗?NO!NO!NO!
当你运行起来,你会看到如下现象:

这Twist怎么又坏掉了?
点开骨骼一看:

原来是我们之前将Mesh下拉,Root也下来了,身体部分随着Pelvis恢复正常,但Root并不会动,导致Knee出现问题,所以此时要对Knee也额外加上脚步的偏移。
这个时候基本就已经完成:
六、融合其他运动状态
1. 不同状态的融合
这个PredictIK在奔跑走路时表现良好,但是如果你加上跳跃、停止等就会出现不可预料的问题。同时在角色刚刚起步时预测IK有些数据没有完全更新,其实是有些问题的,所以我选择在停步时候选择常规IK,而在空中取消IK。

此时你如果尝试着跑一跑,你就会发现下列问题:
2. 奇怪的抖动
这里的抖动除了视频中跳跃之后的抖动,也有刚刚Play移动时候的抖动。
对于空中的抖动是因为在空中落地后是普通IK,没有更新Predict的FootLocation,导致它刚刚进入PredictFootIK时候脚步点还在起跳的地方,就会抖。
所以我的做法是在普通IK的时候也计算更新Foot的Locaton(就是文章开始的第二部分中的预测脚步),同时,如果是在上坡时起跳,会出现人物掉到了墙里,这是因为我们位移了Mesh,所以在切回去的时候没有Offset了,但Mesh位置没还原就会这样,所以在Reset要还原一下Mesh位置,但需要来个插值,不然会瞬移。
同时为了解决开始的抖动,还要Reset一下Pelvis的前后脚位置到Actor的位置(其实不准确,但用下来感觉没影响)。
3. 无法站立
在走到悬崖边缘时,可能出现两个脚的预测都没打到点,或者单脚会出现问题:

对于这个首先要在PredictFoot的时候,如果没预测到,就不要执行PredictFootIK,切回普通IK。但直接切回去会有些问题,还要重置一下IKOffsets。

4. 细节补充
相机我是把Z轴Lag调慢,抖动好很多。
七、待解决问题和最终效果
1. 最终效果
虽然还存在很多问题,但最终效果还是不错的:
更新:在下楼梯时由于射线检测的高度没有设置够,会有时检测不到从而不触发PredictIK(演示视频中存在这个问题),可以通过增高范围解决,但是不宜过大。
2. 待改进问题
A. 对于上不去的坡,Pelvis虽然是落地才抬升,但是脚步会有一个最低的高度(我们预测的路径) 就会有奇怪现象。

这个问题想了一下要解决又要多出很多情况,是否考虑游戏中用一个自动跨上或者攀爬来解决?(有待商榷)
B. 在运动过程中也有很小的概率会脚乱飞,累了不想修了,毕竟小概率。
C. 预测脚步的落点有误差(前面提到过),所以脚步落在边缘是因为如果由于误差缩下来或者缩上去了会有一些抖动。
D. 在上下坡时,脚步切换过程中,起始点会变,所以Mesh高度会变。为了避免跳变我们是有个平滑,但是这个平滑会造成脚步有轻微的浮空,不慢放基本看不出来,就不管了。
参考文章:
Fitting the World: A Biomechanical Approach to Foot IK
这是侑虎科技第1952篇文章,感谢作者Shadow供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)
作者主页:https://www.zhihu.com/people/shadow-21-71-4
再次感谢Shadow的分享,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

