前言
开发时逐渐对蜘蛛网动画系统中重复性的工作感到厌烦,而且当动画一多起来,即使蜘蛛网分了层,我仍然连看都不想看。遂寻求解决方案。
蜘蛛网那一套系统不支持在运行时创建、添加和删除Animation,这使得我们管理众多动画时,需要不断使用override来实现,最后的动画状态机可能庞大而难以维护,这很不好;而Playable提供了更加底层的接口,它允许你在运行时创建、添加和删除Animation,这样也会使得Playable的结构相对简单。
官方介绍指路->Playable API:定制你的动画系统
官方教程指路->可播放项 (Playable) 示例
PlayableGraph
在官方教程有使用例,在Github上下载并导入后方可使用。
PlayableGraph
是一个可播放项的图表。
类似Animator
窗口,但它的组织结构是树状的。根据你在代码中的建树过程和权重设置,它会显示对应的动画流程走向。你无法直接对它进行可视化编辑。
PlayableGraph
包含两个要素,一个是Playable
,一个是PlayableOutput
。前者用于对动画片段(AnimationClip)进行各类操作,包括动画混合、分层蒙版等;后者用于输出操作后的动画,这意味这一个PlayableGraph
至少要有一个PlayableOutput
。
Playable
Playable
是继承IPlayable
接口的 C# 结构体(这避免了Gc alloc)。
和其他可播放项的关系如下,如下。
PlayableOutput
PlayableOutput
是继承IPlayableOutput
接口的 C# 结构体,用于定义 PlayableGraph 的输出。
PlayableOutput
提供SetSourcePlayable
来设置与该输出直接相连的输入项,如下。
playableOutput.SetSourcePlayable(mixerPlayable);
和其他可播放项输出的关系如下。
AnimationClipPlayable
它用来包裹AnimationClip
,使其和 Playable API 相容。
创建方式如下:
AnimationClipPlayable clipPlayable = AnimationClipPlayable.Create(playableGraph, clip);
AnimationMixerPlayable
AnimationMixerPlayable
由它来混合两个动画片段,可以说是相当重要的可播放项。
AnimationMixerPlayable
提供SetInputWeight
方法供外部调整动画之间的权重,如下。
void Update()
{
weight = Mathf.Clamp01(weight);
mixerPlayable.SetInputWeight(0, 1.0f-weight);
mixerPlayable.SetInputWeight(1, weight);
}
从上述用例不难看出,我们通过调整其权重即可实现从某个动画片段到另一个动画片段的过渡,这方便我们自定义动画过渡的插值函数。
如何连接混合器和输入项,如下。
void Start()
{
// 创建 AnimationClipPlayable 并将它们连接到混合器。
mixerPlayable = AnimationMixerPlayable.Create(playableGraph, 2);
var clipPlayable0 = AnimationClipPlayable.Create(playableGraph, clip0);
var clipPlayable1 = AnimationClipPlayable.Create(playableGraph, clip1);
playableGraph.Connect(clipPlayable0, 0, mixerPlayable, 0);
playableGraph.Connect(clipPlayable1, 0, mixerPlayable, 1);
}
也可以在未知输入项数时,动态添加输入项,如下。
mixerPlayable.AddInput(playable, 0, 0f);
自定义动画系统
这里有人分享了他造的轮子,视频指路->【咕咕のUnity学习】Playable 动画系统 2,仓库指路->IrisFenrir/Fenrir-RPG,他对各个功能再次进行了设计和封装,相当不错。
其系统结构如下:
参考资料
Playable API:定制你的动画系统
IrisFenrir/Fenrir-RPG