前言
AdvancedLocomotionV4在FootIK的实现中主要使用Transform Bone设置骨骼位置与虚拟骨骼,最终使用Two Bone Ik完成效果设置。除此之外还使用曲线来控制IK与动画的过度。
AnimGraph部分
因为本人的Demo里角色不需要拿枪,所以Hand IK部分以及后处理动画蓝图中的Ik_Hand_Gun我就略过了。
动画图表中的逻辑主要集中在FootIk动画层中:
动画逻辑分为三个部分:
- 首先计算出FootLock_L/R_Location/Rotation,并将骨骼Ik_Foot_L/R变换到对应位置。使用FootLock_L/R_Alpha变量作为融合Alpha。该操作目的应该是先确定IK效果的大致坐标。(Ik_Foot_L/R是虚拟骨骼 VB IK_Foot_L/R_Offset与VB IK_Knee_Target_L/R的父骨骼)
- 再计算出FootOffset_L/R_Location、FootOffset_L/R_Rotation,将骨骼Ik_Foot_L/R偏移到对应位置。还计算了PelvisOffset偏移了骨盆骨骼。
- 将膝盖处的虚拟骨骼VB Ik_Knee_Target_L与Ik_Knee_Target_R以当前骨骼坐标系偏移vec3(-20,-30,0)vec3(20,30,0),使用Enable_FootIK_L/R权限值控制融合Alpha。
- 调用TwoBoneIk实现最终的FootIK效果。EffectorTarget为虚拟骨骼VB IK_Foot_L/R_Offset,作为位置数据;Joint Target为Ik_Knee_Target_L/R,作为旋转数据。
UpdateGraph
上述所用到的数据皆在动画蓝图的UpdateGraph中的Update Foot IK函数计算。
Update Foot IK
首先调用SetFootLock更新Foot Lock L/R相关数据(在当前动画的当前帧中,IK骨骼的位移值与旋转值)。
之后计算IK骨骼的位移与旋转的偏移值。最后计算骨盆IK偏移。
SetFootLock
- 从指定的曲线中获取浮点值(假定为A)
- 判断 A>=0.99 || A<CurrentFootLockAlpha,就用浮点值A更新CurrentFootLockAlpha(ref)。这样可以实现脚在踏到地面前都不会产生Ik效果,但在收回去会有一定的IK与动画融合的效果。
- 如果 CurrentFootLockAlpha>=0.99,就从指定骨骼处获取Location与Rotation来设置CurrentFootLockLocation(ref)与CurrentFootLockRotation(ref)。
- 如果 CurrentFootLockAlpha>0(有数值),调用SetFootLockOffset函数来更新CurrentFootLockLocation(ref)与CurrentFootLockRotation(ref)。这样做是为了保证在角色在任意移动时,脚部处于都有着正确的位置。
SetFootLockOffset
- 分别从角色类与角色移动类中获取当前旋转值与之前的旋转值,之后计算出两者相差了多少(RotationDifference)
- 获取当前帧与前一帧之间相对于模型的位移的距离。(这一步没完全懂,应该是获取距离之后再进行,世界坐标系=》组件坐标系吧?)
- 计算偏移后的坐标值,并更新LocalLocation(ref)。
- 计算偏移后的旋转值,并更新RotationLocation(ref)。
SetFootOffsets(这一步很关键)
在这个函数中发射了射线。
- 从EnableFootIKCurve曲线中获取浮点值来判断是否对Offset相关变量进行清零。
- 通过ik_foot_l/r与root骨骼计算出脚底坐标,再通过预设的范围变量确定射线检测范围。如果射线有Hit到地面,则对ImpactPoint、ImpactNormal进行赋值,并配合预设变量FootHeight计算出脚的CurrentTargetLocation,最后通过ImpactNormal计算出旋转值并赋值给TargetRotationOffset。
- 通过CurrentTargetLocation对CurrentLocationOffset进行插值计算,从而实现IK的渐变效果。
- 通过TargetRotationOffset对CurrentRotationOffset进行插值计算,从而实现IK的渐变效果。
SetPelvisIKOffset
- 如果有IK效果处于激活状态,则开始骨盆IK计算。
- 比较FootOffset L/R 的Z值,选择往(-Z轴方向)偏移多的,赋值给PelvisTarget。
- 比较PelvisTarget与PelvisOffset的Z值,根据情况对PelvisOffset进行插值计算,从而实现IK的渐变效果。