写在前面
在这篇我将简单介绍下FABRIK的使用, 这是一种逆向运动学(IK)的其中一个算法,主要用来比较自然地调节人物骨骼的移动,可以解决我们人物的左手在枪械上的摆放问题。
FABRIK
所谓IK,是一种和FK相对应的机器人运动算法。比如说用手去抓苹果这一动作,使用FK,可以先旋转你的手臂到一个位置,接着再旋转你的小臂,最后再旋转你的手腕,这样到了最后,你的手就抓到了苹果,是一种自顶向下的过程
从IK的思路走,那就将苹果设置为目标点,你的手掌作为Tip Bone直接去拿苹果,在这个过程中,你的手腕到手臂被带动着一起运动,是一种自底向上的过程。

在这个过程中,我们需要定义两个量,一个为Target(UE 中为Effector Target * Effector Transform, 上图中为t),就是你的p4的目标位置;其次定义你的Effector(在UE中为Tip Bone,上图为p4)还有最上层节点(UE中Rootbone)。
在我们实际的应用中,我们会在我们枪支骨骼上绑定一个LeftHandSocket, 然后计算出这个Socket相对于我们右手骨骼的Bone Space坐标,最后使用FABRIK节点对我们的左手骨骼做变换到相应的Socket位置。
设定LeftHandSocket,得到相应的Target
            
            
              c++
              
              
            
          
          // BlasterAnimation.h
UPROPERTY(BlueprintReadOnly, Category = Character, meta = (AllowPrivateAccess = "true"))
FTransform LeftHandTransfromation;
// BlasterAnimation.cpp
if (BlasterCharacter->GetEquipWeaponComponent() && BlasterCharacter->GetEquipWeaponComponent()->GetEquippedWeapon())
{
       auto EquippedWeapon = BlasterCharacter->GetEquipWeaponComponent()->GetEquippedWeapon();
       // 得到我们左手需要摆放位置的世界坐标 (World Space)
       LeftHandTransfromation = EquippedWeapon->GetMesh()->GetSocketTransform("LeftHandSocket");
       // 将这个World Space的坐标转化为相对于角色右手骨骼的 骨骼坐标 相当于同一个点 但是我从以右手骨骼为原点的坐标系去看
       FVector outPosition;
       FRotator outRotation;
       BlasterCharacter->GetMesh()->TransformToBoneSpace("J_Bip_R_Hand", LeftHandTransfromation.GetLocation(), FRotator::ZeroRotator, outPosition, outRotation);
       // 设置一下Bone Space坐标
       LeftHandTransfromation.SetLocation(outPosition);
       LeftHandTransfromation.SetRotation(FQuat(outRotation));
}在蓝图中使用LeftHandTransformation

如图所示,我们是在已经应用了Aimoffset的动作基础上加的。

点击Play按钮,我们可以边看着PIE边进行LeftHandSocket在枪体位置上的调试

你会发现,现在无论你怎么晃动枪体,你的左手和右手都会紧紧地贴在枪体上了。