写在前面
在这篇我将简单介绍下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在枪体位置上的调试
你会发现,现在无论你怎么晃动枪体,你的左手和右手都会紧紧地贴在枪体上了。