前言
补间动画(Tween Animation)。是十分轻巧的程式动画手段,Godot在手册中把它们藏得很隐晦,目前只在介绍SceneTree的某个章节的某个段落中出现字眼。不过我认为补间动画是很有用的,和官方说的一样,Tween比AnimationPlayer更适合事先不知道最终值的动画。
操作大纲
整体测试下来,发现Tween的使用严格遵循工厂模式类似的形式,即Tween类对象(可以理解为Godot把"一次"补间动画抽象成了一个Tween类对象)本身只能由场景树或某个节点创建,然后用于实现具体逻辑的Tweener(补间器)也只能由Tween对象创建。实现一次补间中用到的所有相关类和对象,都是无法手动创建 的(实际上是可以手动new出来的,不过这样的对象无效),而且是一次性的(其实也并非是一次性的,不过为了避免未知错误就不要犯傻了)。
所以在Godot中使用补间动画具有规范性。有意思的是Tween类和Tweener类其实同级,互不隶属,不过Tween在一次补间中充当管理者,所以由其创建的Tweener会"继承"它的一些设置。比如有些Tweener允许为它们设置TransitionType,我们可以为每一个这样的Tweener单独设置,也可以直接给Tween设置,然后由该Tween创建的Tweener就都默认设置为该Tween的TransitionType了。
Tweeners
目前Godot支持4种补间器:用于回调方法的CallbackTweener;用于调整时间间隔的IntervalTweener;用于持续调用方法的MethodTweener;以及用于改变属性的PropertyTweener。
前两者比较简单,后两者多出一些设置插值方式和缓入缓出的方式,4种补间器都支持蛇者它们的Delay延时。
其中最复杂的是PropertyTweener。它拥有更多方法,比如:
cs
// 以下三个PropertyTweener均可以使某个Node2D向右移动100像素
var tween := create_tween()
tween.tween_property(self, "position", Vector2.RIGHT * 100, 1.0).as_relative()
tween.tween_property(self, "position", position + Vector2.RIGHT * 100, 1.0).from(position)
tween.tween_property(self, "position", position + Vector2.RIGHT * 100, 1.0).from_current()
还能DIY自己的插值方法。
插值方式TransitionType比较重要但又比较抽象,所以我单独做了目前所有TransitionType的示意,不知道怎么选择可以看看:
串联并联
不知道这样称呼合不合适。反正默认情况下,Tweener之间都是串联执行的,也就是一个接着一个这样执行,如果想要让多个Tweener同时执行(并联执行),我们可以通过设置Tween的parallel和set_parrallel修改,前者设置下一个Tweener,后者指示此后的Tweener都并联,可以通过chain把某个Tweener再次跟其他Tweener串联起来。
因为Tween的绝大多数方法都支持链式调用,所以写起来也不会很复杂。控制Tweener的串并联属于Tween的职能。除此之外,Tween还兼顾处理方式,暂停方式,查询状态,控制循环等职能,所以将Tween视为管理器是很合理的。
手动控制
我们可以通过创建一个一开始就是停止或暂停状态的Tween,然后用自定义步数custom_step方法手动控制补间动画的执行.
又或者完全不想用Tween,只是想插值,可以直接使用Tween的静态方法interpolate_value进行手动插值。
结语
总得来说,Godot算是把Unity的DoTween直接嵌入到引擎中了,我觉得在相当多的情况下,程式动画的需求还是非常大的,Godot的补间动画正好弥补这些,当然它和AnimationPlayer一样不止是能用于动画,它最大的限制可能只是人们的想象力。