上次我们说到在 IKinema 中添加自定义模型。方法很简单,就是利用运行时重定向,这次为大家介绍一下具体做法。
Unity 中的重定向(retargeting)大家应该不陌生,重定向使得 Humanoid 模型间可以共享骨骼动画,大大降低了动画的制作成本。但是 Unity 系统的重定向是基于文件的,对于我们使用 Orion 来说,我们需要在 IKinemaMale 模型获得动作信息的同时,将这些信息应用到我们自定义的模型上,这就需要我们在运行时进行重定向。
首先我们需要搞清楚的是,在重定向时发生了什么。Unity 系统中如何实现重定向我们无从得知,而从一段 UE4 的官方视频中,我们可以得到蛛丝马迹:重定向时,(UE4)复制了各关节的旋转角度,想来 Unity 应该也类似。这其实不难理解,因为人的骨骼关节不能位移只能旋转,所以可以忽略位移信息。同时,即使两个人的骨骼比例相差很大,如果他们的每个关节都进行了同样角度的旋转的话,那他们的身体姿势应该也是相同的。所以我们需要做的,就是在运行时,将 IKinemaMale 的各个关节的旋转角度复制到我们的模型上,我们的模型就应该和 IKinameMale 做出同样的动作。这样我们就可以在动捕中用到我们的自定义模型了。
知道了如何重定向,我们来看看在 Unity 中的实现。Unity 内部使用四元数进行旋转运算。根据上面的叙述,我们知道涉及两种运算。一种是四元数相减,即我们需要在运行时将源模型某个关节的所处角度减去该关节的初始角度,得到它的旋转量。另一种当然是四元数相加,我们需要将旋转量,加到目标模型的对应关节上。在四元数中,计算 A 与 B 的差的运算为 A * Inverse(B),而计算 A 与 B 的和则为 A * B。
实际代码如下。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RuntimeRetargeting : MonoBehaviour
{
public Transform srcModel;
Animator srcAnimator;
Animator selfAnimator;
List srcJoints = new List();
List selfJoints = new List();
Quaternion