程序化动画(Procedural Animation)是一种由程序通过 IK 和约束来控制动作的方式形成的动画,适用于动作较复杂的异形角色,如多足机器人、蜘蛛、蛇等。
优点 | 缺点 |
---|---|
易于实现复杂角色的动画,如多足 | 性能不佳 |
动画更连贯 | 动画动作生硬 |
又说连贯,又说生硬,要不要听听你在说什么?
- 连贯是我觉得的。由于受到 IK 驱动,因而不存在动画切换时的快速过渡导致的滑步等问题,动画会更连贯,;
- 生硬是我的动画师朋友觉得的。在他们看来,由 IK 驱动的动画是被动的,不自然。
- 对于这里的主动与被动,我是这样理解的:假设给一个人穿上轮滑鞋,主动就是他自己向前滑,被动就是我们在后面推他往前走,可以想像一下这个差别。
- 当然,我想我们仍然有办法从代码层面让程序化动画看起来更主动,但可能会过于复杂。
如果过于复杂的话,为什么不直接播动画呢?
制作多足角色的程序化动画的流程
绑定 IK
足部的 IK 通常会包含两个控制器:
- 末端控制器(Effector/Target):指示末端的目标位置;
- 极坐标控制器(PoleVector/JointTarget/Hint):指示末端应从哪个方向抵达目标位置。
计算末端的目标位置 Target
末端的目标位置应随着角色移动而变化。由于地面可能高低不平,因此这个目标位置应该是在水平面上像对于锚点的偏移,而高度则通过射线检测得到。
计算目标位置与当前末端控制器所处位置的距离
直接计算欧式距离即可:
d
i
s
t
a
n
c
e
=
Δ
x
2
+
Δ
y
2
+
Δ
z
2
distance = \sqrt{\Delta x^2 + \Delta y^2 + \Delta z^2}
distance=Δx2+Δy2+Δz2
比较距离与容忍度 Endurance
如果距离超过容忍度,则移动末端控制器至目标位置。
- 关于目标位置
与目标位置相关的参数是球心位置,它可以根据当前移动速度变化,即球心应向速度方向偏移。
此外,Hint 也可以向速度方向偏移。
另外还有一点,就是也可以检测一下目标位置的旋转,例如双足的原地旋转。 - 关于容忍度
与容忍度的比较时的主要参数是半径,它也可以根据当前移动速度变化,即半径可以随速率变高而变大。
以防你不知道:这里的比较可以使用平方距离,这样省得开根号。
- 关于末端控制器的移动:
末端控制器可以以曲线的形式进行过渡,即添加一个 y y y轴的曲线,来表示"抬腿"。例如:
y = 4 h t ( 1 − t ) y=4ht(1-t) y=4ht(1−t)
其中, h h h表示抬腿的最大高度, t t t为整体进度(Lerp或SmoothStep的进度)。
调整迈步的模式
可能的迈步模式:
Simple
那条腿出了范围就迈哪条腿。
实际上可能会导致所有的腿同时出范围,因此可能会跳起来(袋鼠麻雀一类的可以用这个,甚至可以两条腿绑一起)。
OneLeft
保证至少有一条腿没有在迈步。
Zigzag
现实中四足或其他腿成对的生物的迈步方式,一侧的序号为奇数和另一侧序号为偶数的腿迈步,其他腿不动。
Sequence
轮流迈动每一条的腿。三足或许可以用这个。
其他
其他特殊情况可以特殊考虑。
比如蚂蚁的步态好像还挺复杂的(小声)
调整躯干的姿态
可以根据当前所有 Effector 的位置来调整躯干的旋转和
y
y
y 轴 Offset。
这一步可以让动画看起来更主动一点;