本文主要关于如何在UE中配置FootIK。其背后的算法、原理因为涉及内容较多,后面会单独另外写一篇。
UE4的动画蓝图中有多个专门给IK用的动画节点,我们比较常用的IK动画节点是TwoBoneIK。下面内容主要关于如何使用TwoBoneIK动画节点来实现基本的脚部IK。此处不包含后期4.26新引入的ControlRig内容(避免和后面UE5部分重复),只纯粹通过动画蓝图动画节点TwoBoneIK实现。
TwoBoneIK只适合比较简单的骨骼脚部骨骼结构(即只有脚踝、膝盖、大腿3个节点),不适合比较复杂的多个骨骼组成的情况(例如大腿-大腿part1-大腿part2-大腿part3-膝盖-膝盖part1-膝盖part2-膝盖part3-脚踝,这类构造)。如果遇到到需要在复杂脚部骨骼上使用的情况,那么就需要在UE中先自行创建虚拟骨骼,将结构简化成大腿-膝盖-脚踝的结构,然后每帧复制原模型骨骼的旋转值到虚拟骨骼,接着通过TwoBoneIK对虚拟骨骼进行IK计算,计算好之后再把虚拟骨骼的位置复制回模型对应的骨骼上。这个过程会比较繁琐,而且容易写错。
接下来我们看一个用TwoBoneIK节点实现IK的例子。这个示例使用了官方第三人称demo来二次开发。运行demo,可以看到原版UE4官方第三人称demo没有设置脚部IK:
小白人在楼梯这类地方脚可能会悬空,而不是身体向下移动,让两只脚都踏在台阶上。
接下来我们在动画蓝图中引入TwoBoneIK节点并指定好参数即可配置好TwoBoneIK。我们先看看TwoBoneIK节点暴露出来可以配置的参数:
重点其实是在Effector和JointTarget的设置上。TwoBoneIK节点封装得比较好,只需要设定好参数,传入EffectorTarget目标位置就可以实现脚部IK。
首先在动画蓝图中创建两个TwoBoneIK动画节点,并分别对左右脚进行配置,同时对Pelvis骨骼进行位置调整,即对模型整体位置进行调整:
其中TwoBoneIK动画节点参数配置如下图所示:
对Pelvis骨骼的设置如下图所示:
另外,之所以时Pelvis是因为Pelvis是除了Root骨骼之外的最顶层骨骼,相当于对整体骨骼进行一个偏移:
我们先暂时忽略掉前面几个Offset变量在哪里更新的问题,等等再回到这部分。接下来我们去到小白人的角色蓝图,并制作下面的蓝图函数:
这个函数主要用处就是根据给定的骨骼(虽然函数名字叫做GetSocketLocation,但是实际上在UE里面没区分这么严格,骨骼也可以是Socket)和给定的检测距离\(d\),在给定骨骼的位置上方\(\frac{d}{2}\)高度开始,向地板方向进行射线检测,检测总长度为给定的检测距离\(d\)。最后通过射线检测到的碰撞位置(即射线与地面的交点)\(\overrightarrow{r_{\mathrm{hit}}}\)、射线末端位置\(\overrightarrow{r_{\mathrm{end}}}\)、射线长度\(d\),计算出碰撞位置到射线末端的长度\(d_{2}\),由\(\frac{d}{2}-d_2\)得出脚到地面的距离(其实是胶囊体底部到地面的距离,但是通常我们会保证模型默认姿势时脚就在胶囊体底部位置上,所以最终计算结果是一样的)。
下图是站在地面的情况,此时末端到地面长度与射线长度的一半,即\(\frac{d}{2}\),一致,所以不需要偏移:
在一只脚在高处一只脚在低处的时候可以看到,较低处的脚会需要偏移(不偏移的话会浮在空中,就像前面没有添加IK时候的那样),偏移量就靠我们前面的函数计算得出:
上图就是IK前的状态,我们计算得出偏移量之后对根节点往下偏移(否则左脚无法站在下面的地面上),同时将左脚上的IKEffector移动到较低的地面上。
最终得到:
其实上面缺了一个步骤,毕竟上面只是制作了计算偏移量的函数,还没有调用。因此我们需要在角色蓝图的Tick中进行调用:
上图的流程:
随后,我们回到动画蓝图,我们将会在动画蓝图的Update函数中读取上面角色蓝图里面记录的变量:
这里我们封装读取变量的部分成一个名为UpdateOffset的函数,其定义如下:
这里要和HipOffset相减是我们动画蓝图里面会用HipOffset来调整Pelvis的高度,因此需要剪掉这部分避免重复偏移。
最后动画蓝图运行的时候根据计算出的偏移量进行偏移:
最终实现效果:
可以看到已经没有出现前面的脚浮空的问题了。
没有IK骨骼的话得要手动创建虚拟骨骼,简化模型骨骼。动画蓝图流程编程:
其他部分,计算距离等步骤和上面一致。
UE4.26中引入了ControlRig,但是实际上到UE5.0才算稳定下来。所以我将ControlRig设置IK的部分放在这里,并且是在UE5项目中实现。
用ControRig实现的另一个原因是,UE官方推荐脚部IK之类的动画优化都放在ControlRig中进行处理。这样动画蓝图可以专注动画切换逻辑处理,而不用把动画优化和切换混在一起导致动画逻辑混乱。
官方介绍:
总而言之,就是用来方便操作、控制动画的一套操控系统:
MetaHuman项目中就通过ControlRig实现了复杂的表情系统:
下面主要解析一下官方Demo实现的IK,这里的Demo是UE5内置的第三人称模版Demo。
首先我们看看第三人称模板中实现的脚部IK效果:
可以看到看起来实现还是不错的。
首先我们看看ControlRig的总览(可能看不太清楚,不过没有关系,我会在后面详细介绍每一步做了什么):
其实就分了5个步骤:
接下来我们分步骤进行分析。
先看总览:
首先判断是否要进行IK,这里判断依据的变量ShouldDoIKTrace是暴露出去的,可以在动画蓝图外面控制。如果不进行IK的话会把双脚的Z方向Offset设为0,即不需要改变脚部高度。
如果进行IK,那么会调用FootTrace函数来获取脚到地面的距离,我们看下这个函数的实现。
可以看到函数所做的事情:
射线路径如下图所示:
我们分开真正的目标值(第一步设置的)与当前脚部的偏移值,用AlphaInterpolate函数进行插值计算出脚部新的偏移值,后面再把计算出来的新偏移值设置到脚部上。这一步主要是平滑动画用,避免脚部位置突变。
取测量出的两脚到地面的距离,取最大距离作为腰部的偏移值。这么做是为了能够让模型总体向下移动,从而保证位置较低的脚能够站在地面上:
这里之所以用Less来进行判断,是因为我们前面FootTrace函数中返回的是射线与物品碰撞点的坐标,而我们直接把碰撞点世界坐标Z轴的值设置为偏移量,因此Z越小,就代表脚到地面越低,脚离地面的距离越可能大(因为实际上这里我们没有计算距离,所以只是可能):
如果不取距离最大的值来设置模型的高度偏移量,那么很可能因为脚不够长而导致脚必须通过拉伸才能够被放置在地面上。
另外,上面的腰部指Pelvis,即模型的第二层骨骼:
设置Pelvis骨骼的位置能够影响整个模型的位置。
这一步更新双脚对应的IK骨骼的位置,以及Pelvis骨骼位置。这里只是简单的在世界空间中,Z轴上添加了偏移量。之所以不直接更新双脚位置是因为如果需要调整双脚的位置,还需要顺带更新双脚父骨骼的位置、旋转值,即必须借助IK算法来进行更新。这里IK骨骼其实相当于一个临时变量,用来暂存更新后的位置数据。
这一步读取上一步IK骨骼更新后的位置数据,并设置给双脚骨骼Effector目标位置,让IK算法依据目标位置反推父骨骼位置、角度,让双脚移动到目标位置上。
这样就基本实现脚部IK了,可以看到角色双脚可以适配各类高低地形,不会出现浮空的现象:
但是还有点瑕疵,在斜面上的时候脚会有一部分穿入地面,而且也不能够贴合地面:
如果要修复这个问题,就需要利用第二步射线检测到的斜面倾斜角度,修正脚部角度,使得脚部贴合地面。
最后,记得在动画蓝图加上ControlRig节点,让动画生效即可:
(忽略掉ControlRig后面一系列节点,那部分是其他的优化,与脚部IK无关)。
ControlRig节点记得配置属性这里,指定好对应的ControlRigClass: