2D IK | 2D 反向动力学

这个工具包中包含了一些依据反向动力学在给定一个目标位置的前提下确定与该移动有关的一系列组件移动
后的位置的工具。这将会使得你给角色在动画中摆个姿势更加方便,也可以帮助你实时操纵角色。

工作流程

  • 设置你需要应用IK的 transform。
  • 为IK创建一个 GameObject。
  • 在这个 GameObject 上添加 IKManager2D 组件。
  • 在 IK Solvers 菜单中,点击 + 来创建你的IK求解器。这会为每个新的IK求解器建立一个 GameObject。
  • 设置单独的IK求解器,每个求解器特有的参数会列在下面。
  • 如果你想要的话,可以为每个单独的求解器设定效应器。在你有实时IK的时候这会很有用。
  • 在所有IK求解器创建出来之后, 在 IKManager2D 中按优先级安排IK求解器。 在列表中位置越往下的IK求解器会越优先于前面的。
  • 设置好使用效应器的 Transform,或者在 SceneView 中摆好你的模型。
  • 好用吧!

IK管理器(IK Manager)

这个组件控制并且驱动着这个工具包中的所有IK求解器。
你需要添加这个到一个用来控制一个给定层级上的 Transform 的 GameObject 上。
没有IK管理器的IK求解器不会生效。

属性(为了对照方便,属性名称的翻译作为注释处理):

  • Weight(权重): 这个权重是影响IK管理器控制的所有求解器的权重。这个权重会被应用到所有求解器的权重上,并且还会被用到混合IK求解器位置的结果和这些被影响的Transform原本的位置。
  • Solvers(求解器): 这是一个IK管理器控制的所有求解器的列表。把所有IK求解器放进这个列表可以让它们按照优先级运行。在列表中位置越往下的IK求解器优先级会越高,因为它们是一个接一个按列表顺序进行迭代的。

求解器(Solvers)

这些是工具包中自带的求解器。你可以为自己的IK题目选择合适的求解器。

Solver2D

以下是所有求解器中通用的属性:

  • Constrain Rotation(旋转约束):这个属性将目标的旋转属性约束到了效应器的旋转属性上。
  • Restore Default Pose(恢复默认姿态):这个属性将会把受影响的Transform恢复到IK的解被应用之前的位置。
  • Weight(权重):这个权重是用来混合IK求解器位置和被影响的Transform的原本位置的权重。值为0意味着当一个权重为1的IK解完全应用的时候,这个IK解会被无视掉。这个权重会和管理器的权重相乘。
Limb(手臂)

这是一个标准的双骨骼求解器。

  • Flip(翻转):使用这个属性可以翻转求解器的结果。
  • Effector(效应器):为达到期望中的位置实现IK的使用一个transform。
  • Target(目标):作为效应器的期望中的位置使用的一个transform。
CCD (Cyclic Coordinate Descent)(循环坐标下降)

这个求解器在求解IK的过程中使用了循环坐标下降算法。
这是一个会产生近似解并且在算法运行过程中逐渐接近更优解的迭代型求解器。
因此在运行到容差范围内或者达到最大运行步数之前可能不会达到精确解。

  • Effector(效应器):为达到期望中的位置实现IK的使用一个transform。.
  • Target(目标):作为效应器的期望中的位置使用的一个transform。
  • Chain Length(链表长度):从目标开始包含在IK解中的transform数。
  • Iterations(迭代次数):没达到期望位置之前,这个求解器会运行的次数。
  • Tolerance(容差):求解器停止运行之前目标解需要多接近期望位置。
  • Velocity(速率):链表中的transform朝期望位置迭代的速度。这个值高意味着链表中的初始部分会快速向期望位置旋转,可能会导致链表中后续的部分在已经达到期望位置后就不会继续旋转了。这个值低就意味着链表中后续的部分会更多地被包含进IK解。
FABRIK (Forward And Backward Reaching Inverse Kinematics)(摇摆接近IK)

这个求解器使用了摇摆接近算法来求解IK。
这也是一个会产生近似解并且在算法运行过程中逐渐接近更优解的迭代型求解器。
因此在运行到容差范围内或者达到最大运行步数之前可能不会达到精确解。

  • Effector(效应器):为达到期望中的位置实现IK的使用一个transform。
  • Target(目标):作为效应器的期望中的位置使用的一个transform。
  • Chain Length(链表长度):从目标开始包含在IK解中的transform数。
  • Iterations(迭代次数):没达到期望位置之前,这个求解器会运行的次数。
  • Tolerance(容差):求解器停止运行之前目标解需要多接近期望位置。

添加新求解器

你可以通过从Solver2D类中继承的方式来添加你自己的求解器。
你继承的类会在IKManager2D组件中的求解器菜单下方显示。

Solver2D

这是这个工具包中所有IK求解器的基类。
IKManager2D会检测所有这个类的继承类,并且把它们认作自己可以控制的求解器。
执行或者重载以下方法可以创建你自己的IK求解器:

  • protected abstract int GetChainCount() 这个函数返回这个求解器拥有的IK链表数目。你可以用它来返回你自己的求解器拥有的IK链表数目。
  • public abstract IKChain2D GetChain(int index) 这个函数返回处在给定序号的位置上的IKChain2D。你可以用它来返回你的求解器在给定序号的位置上的IKChain2D。
  • protected virtual bool DoValidate() 这个函数校验每个传入求解器的函数。你可以用它来检验你的求解器是否所有输入都设置正确。
  • protected virtual void DoInitialize() 这个函数会初始化求解器同时构建这个求解器拥有的IK链表。这个函数会在改变这个求解器的目标值或者其他参数之后任何这个求解器是无效的的时候被调用。你可以用它来用所有求解器中给定的参数来初始化所有的数据,比如这个求解器拥有的IK链表。
  • protected virtual void DoPrepare() 这个函数会将Transform的信息(position、rotation、IK参数等)准备好并且转换成IK算法可以利用的结构。你可以用这个函数在刷新IK位置的时候来做任何收集你的求解器使用的数据的工作。
  • protected abstract void DoUpdateIK(List effectorPositions) 为求解器拥有的每个链表给出一列效应器,
    这个函数会为求解器控制的Transform计算并且设置期望的IK位置。如果用户在场景中操作了效应器位置,计算的位置可能会被过载。
  • protected virtual Transform GetPlaneRootTransform() 这个函数会返回本地XY平面被用来进行IK运算的transform。你可以用它来定义使用的Transform。
IKChain2D

这是用来存储包含在一个IK链表里的transform的类。当链表设置好一个目标和transform数目的时候,求解器的初始化会在有效状态下向链表填入正确的transform

  • Target(目标):作为效应器的期望中的位置使用的一个transform。
  • Effector(效应器):为达到期望中的位置实现IK的使用一个transform。
  • TransformCount(transform数目):从目标开始包含进IK解的transform的数目。在求解器中这大体上和链表长度等价。
  • Transforms:所有包含进链表的transform。大体上来说,最后一个transform是目标,第一个transfom应该是链表的根transform。
  • Lengths(长度):链表中每个transform之间的长度。
Solver2DMenu

这个属性允许你在IKManager2D下用不同的名称给你的Solver2D打标签。
如果你不想看见Solver2D的类名称的话就用这个吧。

LimbSolver2D示例: [Solver2DMenuAttribute("Limb")]

翻译对照表

术语

译文

Base class

基类

Chain

链表

Class


Effector

效应器

Function

函数

Iteration

迭代

Manager

管理器

Method

方法

Populate

填入

Solver

求解器

Tolerance

容差

Weight

权重