原因
在使用 Unity 开发游戏过程中,经常使用到 Animation 功能来为物体做动画效果,其中就包括物体的位移路径动画,比如过场动画里镜头的路径移动等。现有的 Animation 功能只能编辑关键帧所在时刻的物体位置,而无法一览物体路径动画的轨迹,造成美术人员编辑路径动画时,没办法直观的查看所编辑的路径曲线。另外,在 Animation 窗口里进行调整曲线的切线,非常的不便,只能在180度的斜率范围内调整数值。
目标
实现实时的动画路径预览,快速定位关键帧,方便编辑切线。
解决
为了可以实时预览动画路径,那么就需要获得当前 Animation 窗口的动画数据,但是 Unity 不开放操作 Animation 窗口类,只能通过反射来处理。 创建的 AnimationWindowUtil 类,即是为了与 Animation 窗口的数据进行交互。
动画数据里面存储的是使用埃尔米特(Hermite)曲线公式的值,它是使用各个顶点的斜率来构建曲线,这也造成了在 Animation 窗口编辑切线的不便,没法精确控制斜率的值。
合适的方式是使用贝塞尔(Bézier)曲线,它提供了两个控制点来调整切线,控制点的位置比起控制斜率的值大小来的直观方便多了。好在这两种曲线公式是可以转换的,Hermite 曲线转换成 Bézier 曲线步骤如下:
P0(b) = P0(h)
P1(b) = P0(h) + M0(h) * 1/3
P2(b) = P1(h) - M1(h) * 1/3
P3(b) = P1(h)
转换完成之后,则可通过绘制 Bézier 曲线,将动画路径展现出来。
绘制的绿色点是每个关键帧的位置,点中绿色点,即可直接在 Animation 窗口定位到当前关键帧,方便直接立即编辑。点中绿色点时,会在该点的旁边出现灰色控制点,直接点中控制点,就可以直接调整该点的切线了。
这样来调整切线比在 Animation 窗口里面进行调整斜率方便的多了。切线调整完成后,通过 Bézier 曲线转换成 Hermite 曲线,来写回动画数据。
当关键帧过多时,可能会遮挡住曲线的走向绘制,特别是在转弯的地方,故也提供关闭显示关键帧点的功能。
结语
Unity 编辑器开放的接口不能够实现于想要实现的功能时,只能反编译编辑器代码,分析相应所封闭起来的功能代码,才能获取到想要的数据。动画数据存储的是 Hermite 曲线公式,而这种曲线无法在场景里面进行方便的调整,只能通过转换成 Bézier 曲线。