Final IK学习笔记5:Aim IK

AimIK求解器是CCD算法的一种修改,它旋转骨骼层次结构以使子层朝向目标。它与基本的内置Animator.SetLookAtPosition或LookAtIK功能不同,因为它能够准确地瞄准未与层次结构的主轴对齐的目标。

AimIK可以产生非常稳定和自然的重新定位角色动画,因此在武器瞄准系统中具有很大的潜力。通过AimIK,我们可以设置单个前向瞄准姿势或动画,以瞄准目标(甚至几乎在角色后面的目标)。只有位于180度偏移的四元数奇点,求解器无法知道转向脊柱的方向。就像LookAtIK一样,AimIK提供了clampWeight属性,以避免出现奇点问题。

AimIK也适用于旋转限制,但是如果链受到严格约束,它比其他受约束的求解器更容易卡住。


Final IK学习笔记5:Aim IK_第1张图片
AimIK求解器

使用步骤:

  • 设置角色的Animator/Animation以播放瞄准前进动画/姿势
  • 将AimIK组件添加到角色中
  • 将spine骨骼分配给组件中的“ Bones”,逐个降序排列(父项优先)。
  • 指定目标Transform(您想要瞄准目标的Transform)。 它可能是枪,手骨或只是手上的空游戏对象
  • 确保Axis表示您希望瞄准目标的Aim Transform的局部轴。 例如,如果枪的(z)轴指向它的枪管,则需要将轴设置为(0,0,1)。
  • 将weight设置为1,按“Play”
  • 在场景视图中移动目标以查看AimIK的更新

组件参数:

  • timeStep - 如果为零,将更新每个LateUpdate()中的求解器,用于骨骼带动画时的情况。 如果大于零,将按频率更新,以便求解器将在所有对象上同时到达其目标。
  • fixTransforms - 如果为true,则将解算器使用的所有Transforms修复为每个Update中的初始状态。 这可以防止没有动画骨骼和animator的剔除的问题,并且性能成本很低。

求解参数:

  • target - 目标物体。如果已分配,则解算器IKPosition将自动设置为目标的位置。
  • poleTarget - 如果已分配,将自动将polePosition设置为此Transform的位置。 IKSolverAim.polePosition使Aim Transform的另一个轴(poleAxis)朝向IKSolverAim.polePosition。
  • Aim transform - (目标变换)我们想要瞄准IKPosition的变换(通常是枪或手电筒,在上图中表示为粉红色圆锥)。
  • axis - 要将目标指向IKPosition的Aim Transform的局部坐标的轴。例如,如果枪的蓝色(z)轴指向它的枪管,则需要将轴设置为(0,0,1)。
  • poleAxis - 希望保持面向IKSolverAim.polePosition的Aim Transform的局部坐标的轴
  • weight - 混合IK效果的权重
  • poleWeight - 保持AimTransform的poleAxis朝向polePosition的权重
  • tolerance - 距离最后到达角度的最小偏移量。如果与先前达到的角度的差异小于容差,则将停止求解。如果容差为零,将迭代直到maxIterations。
  • maxIterations - 每帧最大迭代次数。如果tolerance为0,则将一直迭代直到maxIterations
  • clampWeight - solver的旋转取值。 0是自由旋转,1是完全固定到没有效果。
  • clampSmoothing - 正弦平滑迭代次数。
  • bones - 用于将目标变换定向到目标的骨骼。所有骨骼都需要是Aim Transform的直接父节点,并按降序排序。您可以跳过层次结构中的骨骼,也可以包含Aim Transform本身。骨骼层次结构不能分支,这意味着您无法从双手分配骨骼。骨骼权重决定了混合层次结构的强度。


    Final IK学习笔记5:Aim IK_第2张图片
    AimIK组件

脚本参考如下:

  • Solver
  • Component

改变目标:

public AimIK aimIK;
void LateUpdate () {
    aimIK.solver.IKPosition = something;
}

使用Pole:
在制作武器瞄准设置时,polePosition可能会有所帮助。 假设我们有一把枪,局部坐标的Z轴朝向它的枪管,局部坐标的Y轴朝上。 在这种情况下,我们必须将AimIK的“Axis”设置为(0,0,1),将“Pole Axis”设置为(0,1,0)。 如果我们现在播放场景并将“ Weight”和“Pole Weight设置为1,我们将有2个控制点,一个用于瞄准目标,另一个用于扭转枪和角色的身体。

通过脚本调整Pole:

public AimIK aimIK;
void LateUpdate () {
    aimIK.solver.transform = something;
    aimIK.solver.axis = localAxisOfTheTransformToAimAtTheTarget;
}

在运行时添加AimIK:

public AimIK aimIK;
public Transform[] newBones;
void Change() {
    aimIK.solver.SetChain(newBones, aim.transform);
}

使用具有旋转限制的AimIK:
有时需要限制AimIK对其链中一个骨骼的影响。 通常当您希望在瞄准单手武器的过程中使用肘关节时,或者当您希望限制脊椎骨的旋转仅是扭转时。 如果您刚刚将RotationLimit组件添加到骨骼中,它也会干扰动画(保持脊柱僵硬),而不仅仅是IK。 您可以通过在AimIK解决之前设置每帧旋转为默认来使RotationLimit对AimIK产生影响。

public AimIK aimIK;
void LateUpdate() {
    // Set current animated localRotation as default local rotation for the rotation limits so they will not interfere with the animation, but only the IK
    for (int i = 0; i < aimIK.solver.bones.Length; i++) {
        if (aimIK.solver.bones[i].rotationLimit != null) {
            aimIK.solver.bones[i].rotationLimit.SetDefaultLocalRotation();
        }
    }
}

请注意,每个RotationLimit都会降低求解器平滑到达目标的概率。
由于FinalIK 0.4引入了polePosition和poleWeight,因此在大多数情况下,通过使用Pole来保持身体直立,可以避免对角色使用旋转限制。

骨骼权重
“Bones”中的每个骨骼都有一个权重参数。它决定了在求解过程中使用的骨骼的比重。 例如,如果你不希望某个脊椎骨弯得太多,你可以减轻它的权重。

双手武器的瞄准:
当使用双手武器时,我们只能在AimIK骨骼层次结构中使用脊柱骨骼(双手的共同父节点)。如果我们使用手臂骨骼,另一只手会松动与物体的接触。有时只使用脊柱骨骼是不够的,因为脊柱会过度弯曲而角色变成不自然的姿势。我们可以通过在AimIK上添加一些手臂骨骼(握住物体的手臂),在AimIK完成后,使用FullBodyBipedIK或LimbIK将另一只手放回原位。

重定向动画:
AimIK非常适合保持物体稳定地瞄准目标。有时这些物体在动画中有很多摆动动作,例如摆动剑,并且在挥杆过程中使用AimIK来保持剑定位在某个位置是不好的。它会通过弯曲层次结构的其余部分来保持剑的方向,并以不必要的方式干扰动画。仍然可以使用AimIK重定向摇摆动画,如剑术或拳击,但是需要一些技巧,可以参考这个视频。

在瞄准时换武器或者重新加载动画:
当AimIK权重为1时,solver将始终保持武器朝向目标。换武器或重新加载动画时,这可能是不必要的。我们可以动态更改AimIK的Axis来克服这个问题。

void LateUpdate() {
        aimIK.solver.axis = aimIK.solver.transform.InverseTransformDirection(character.forward);
}

通过上面的代码,无论动画中武器的方向如何,它都是默认的前向瞄准方向。 “Character.forward”是没有任何后坐力时武器瞄准的方向(保持方向在角色空间中以使武器与角色一起旋转)。如果你当前正在播放“瞄准右边”的动画, 你应该把它设置为“character.right”。

你可能感兴趣的:(Final IK学习笔记5:Aim IK)