同步系列16-FABRIK IK修复手部动画


不使用IK时,有时候动画和模型是分离的,并不贴合。

image-20230505205915176

遇到这种情况可以使用FABRIK。

先在动画实例C++中创建我们需要的变量,因为我们要把左手附加在武器的某个位置上,所以我们需要左手的三维信息。

1
2
3
4
5
6
7
class BLASTERAGAIN_API UBlasterAnimInstance : public UAnimInstance
{
private:
UPROPERTY(BlueprintReadOnly, Category = Movement, meta = (AllowPrivateAccess = "true"))
FTransform LeftHandTransform;
}

之后在cpp中最新的位置添加:

1
2
3
4
5
6
7
8
9
if (bWeaponEquipped && EquippedWeapon && EquippedWeapon->GetWeaponMesh() && BlasterCharacter->GetMesh())//FABRIK IK
{
LeftHandTransform = EquippedWeapon->GetWeaponMesh()->GetSocketTransform(FName("LeftHandSocket"), ERelativeTransformSpace::RTS_World);//**获取武器插槽的三维信息
FVector OutPosition;
FRotator OutRotation;
BlasterCharacter->GetMesh()->TransformToBoneSpace(FName("hand_r"), LeftHandTransform.GetLocation(), FRotator::ZeroRotator, OutPosition, OutRotation);
LeftHandTransform.SetLocation(OutPosition);
LeftHandTransform.SetRotation(FQuat(OutRotation));//**参数类型是**const TQuat<T>& NewRotation* *所以需要用**using FQuat = UE::Math::TQuat<double>;
}

这样在持有武器的时候就可以获取武器上名为“LeftHandSocket”的插槽的位置信息并赋给LeftHandTransform了。当然获取哪个插槽信息完全可以自己改,之后创建的OutPosition和OutRotation填入到TransformToBoneSpace转换到骨骼空间,这个函数可以计算输入给与的位置和旋转(InPosition,InRotation)相较于指定骨骼(FName(“hand_r”)),产生的值输入的位置旋转相较于指定骨骼的位置旋转的偏移值。产生的值会被填入OutPosition、OutRotation。然后我们最后设置一下LeftHandTransform的位置和,旋转,那么手上骨骼的位置就和枪械插槽的位置重合了。最后我们还需要去动画蓝图设置一下IK身体骨骼,某个骨骼位置动了,身体的一部分需要跟着一起动,不然产生的效果就是局部被拉伸,会很难看。

新建状态机

image-20230505213123099

image-20230505213400289

最后看一下效果,记得给武器添加LeftHandSocket插槽,如果位置不太对可以在运行的时候移动武器插槽的位置进行调整,达到一个满意的效果。

image-20230505213508629


文章作者: John Doe
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 John Doe !
  目录