Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
AnimationMixer
派生: AnimationPlayer, AnimationTree
AnimationPlayer 和 AnimationTree 的基类。
描述
AnimationPlayer 和 AnimationTree 的基类,用于管理动画列表。同时还提供了用于播放和混合的常用属性和方法。
在扩展后的类中实例化播放信息数据后,就会由 AnimationMixer 负责处理混合。
教程
属性
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
方法
_post_process_key_value(animation: Animation, track: int, value: Variant, object_id: int, object_sub_idx: int) virtual const |
|
add_animation_library(name: StringName, library: AnimationLibrary) |
|
void |
|
void |
capture(name: StringName, duration: float, trans_type: TransitionType = 0, ease_type: EaseType = 0) |
void |
|
find_animation(animation: Animation) const |
|
find_animation_library(animation: Animation) const |
|
get_animation(name: StringName) const |
|
get_animation_library(name: StringName) const |
|
get_animation_library_list() const |
|
get_animation_list() const |
|
get_root_motion_position() const |
|
get_root_motion_rotation() const |
|
get_root_motion_scale() const |
|
has_animation(name: StringName) const |
|
has_animation_library(name: StringName) const |
|
void |
|
void |
rename_animation_library(name: StringName, newname: StringName) |
信号
animation_finished(anim_name: StringName) 🔗
动画播放结束时通知。
注意:如果动画正在循环播放,则不会发出此信号。
animation_libraries_updated() 🔗
当动画库发生更改时发出通知。
animation_list_changed() 🔗
当动画列表发生更改时发出通知。
animation_started(anim_name: StringName) 🔗
当动画开始播放时发出通知。
caches_cleared() 🔗
当缓存被清除时通知,可以是自动清除,也可以是通过 clear_caches() 手动清除。
mixer_applied() 🔗
当相关的混合结果应用于目标对象时发出通知。
mixer_updated() 🔗
当处理相关属性发生更改时发出通知。
枚举
enum AnimationCallbackModeProcess: 🔗
AnimationCallbackModeProcess ANIMATION_CALLBACK_MODE_PROCESS_PHYSICS = 0
在物理帧中处理动画(见 Node.NOTIFICATION_INTERNAL_PHYSICS_PROCESS)。尤其适用于对物理体进行动画处理。
AnimationCallbackModeProcess ANIMATION_CALLBACK_MODE_PROCESS_IDLE = 1
在处理帧中处理动画(见 Node.NOTIFICATION_INTERNAL_PROCESS)。
AnimationCallbackModeProcess ANIMATION_CALLBACK_MODE_PROCESS_MANUAL = 2
不处理动画。使用advance()手动处理动画。
enum AnimationCallbackModeMethod: 🔗
AnimationCallbackModeMethod ANIMATION_CALLBACK_MODE_METHOD_DEFERRED = 0
在动画过程中批量调用方法,然后在处理完事件后再进行调用。这样就避免了在播放过程中涉及删除节点或修改AnimationPlayer的错误。
AnimationCallbackModeMethod ANIMATION_CALLBACK_MODE_METHOD_IMMEDIATE = 1
在动画中达到时立即进行方法调用。
enum AnimationCallbackModeDiscrete: 🔗
AnimationCallbackModeDiscrete ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT = 0
将 Animation.UPDATE_CONTINUOUS 或 Animation.UPDATE_CAPTURE 轨道值与 Animation.UPDATE_DISCRETE 轨道值混合时,Animation.UPDATE_DISCRETE 轨道值优先。
AnimationCallbackModeDiscrete ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE = 1
将 Animation.UPDATE_CONTINUOUS 或 Animation.UPDATE_CAPTURE 轨道值与 Animation.UPDATE_DISCRETE 轨道值混合时,Animation.UPDATE_CONTINUOUS 或 Animation.UPDATE_CAPTURE 轨道值优先。这是 AnimationPlayer 的默认行为。
AnimationCallbackModeDiscrete ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS = 2
始终将 Animation.UPDATE_DISCRETE 轨道的值视为 Animation.UPDATE_CONTINUOUS 和 Animation.INTERPOLATION_NEAREST。这是 AnimationTree 的默认行为。
如果值轨道上关键帧的值为无法插值的类型,则会在内部转换为 ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE 和 Animation.UPDATE_DISCRETE。
无法插值的类型列表:
@GlobalScope.TYPE_BOOL 和 @GlobalScope.TYPE_INT 在混合时会被视为 @GlobalScope.TYPE_FLOAT,获取值时会四舍五入。
数组和向量同理,以 @GlobalScope.TYPE_PACKED_INT32_ARRAY 和 @GlobalScope.TYPE_VECTOR2I 为例,它们会被视为 @GlobalScope.TYPE_PACKED_FLOAT32_ARRAY 和 @GlobalScope.TYPE_VECTOR2。另外请注意,数组的大小也会发生插值。
@GlobalScope.TYPE_STRING 和 @GlobalScope.TYPE_STRING_NAME 的字符代码和长度会发生插值,但是关键帧的插值和混合时的插值在算法上有区别。
属性说明
如果 true
时,AnimationMixer 将执行逻辑处理。
int audio_max_polyphony = 32
🔗
每个指定的 AudioStreamPlayer 可能同时发出的声音的数量。
例如,如果该值为 32
并且动画有两个音轨,则分配的两个 AudioStreamPlayer 可以同时播放最多 32
个声音。
AnimationCallbackModeDiscrete callback_mode_discrete = 1
🔗
void set_callback_mode_discrete(value: AnimationCallbackModeDiscrete)
AnimationCallbackModeDiscrete get_callback_mode_discrete()
一般而言,可以将轨道设置为 Animation.UPDATE_DISCRETE 降低更新频率,通常在最近邻插值时使用。
但在使用 Animation.UPDATE_CONTINUOUS 进行混合时需要考虑不同的结果,可以用 callback_mode_discrete 来显式指定。另见 AnimationCallbackModeDiscrete。
为了在混合时得到更好的结果,建议将其设置为 ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS,在混合时每一帧都更新。其他值主要用于兼容,在不需要混合时没有问题,但需要混合时则可能产生问题。
AnimationCallbackModeMethod callback_mode_method = 0
🔗
void set_callback_mode_method(value: AnimationCallbackModeMethod)
AnimationCallbackModeMethod get_callback_mode_method()
用于“方法调用”轨道的调用模式。
AnimationCallbackModeProcess callback_mode_process = 1
🔗
void set_callback_mode_process(value: AnimationCallbackModeProcess)
AnimationCallbackModeProcess get_callback_mode_process()
更新动画的过程通知。
如果为 true
,则混合使用确定性算法。总权重不进行归一化,在初始值的基础上进行累加(初始值为 0
,表示可能存在的 "RESET"
动画)。
这意味着如果混合总权重为 0.0
,则结果等于 "RESET"
动画。
如果混合动画之间的轨道数量不同,则缺少轨道的动画将被视为具有初始值。
如果为 false
,则混合不会使用确定性算法。总权重将归一化且始终为 1.0
。如果混合动画之间的轨道数量不同,则不会对缺少轨道的动画执行任何操作。
注意:在 AnimationTree 中,与 AnimationNodeAdd2 、 AnimationNodeAdd3 、 AnimationNodeSub2 或权重大于 1.0
混合可能产生意想不到的结果。
例如,如果 AnimationNodeAdd2 混合了两个取值为 1.0
的节点,则总权重为 2.0
,但它将被归一化使总权重保持 1.0
,且结果将等于取值为 0.5
的 AnimationNodeBlend2。
由编辑器使用。如果设置为 true
,场景将被保存,并应用重置动画(带有键 "RESET"
的动画)的效果,就好像它已被定位到时间 0 一样,编辑器保留场景在保存之前的值。
这使得在编辑器中预览和编辑动画更加方便,因为对场景的更改,只要在重置动画中被设置,就不会被保存。
如果为 true
,则混合前会将 get_root_motion_position() 的值当作局部平移值提取。换句话说,会被当作在旋转后再进行平移。
NodePath root_motion_track = NodePath("")
🔗
用于根部运动的动画轨道的路径。路径必须是指向某一节点的有效场景树路径,必须从将实现动画的节点的父节点开始指定。root_motion_track 使用与 Animation.track_set_path() 相同的格式,但注意必须指定一个骨骼。
如果轨道的类型是 Animation.TYPE_POSITION_3D、Animation.TYPE_ROTATION_3D、或者 Animation.TYPE_SCALE_3D,那么将取消视觉上的变换,其动画看起来将是留在原地。另见 get_root_motion_position()、get_root_motion_rotation()、get_root_motion_scale()、RootMotionView。
NodePath root_node = NodePath("..")
🔗
节点路径引用将从其出发的节点。
方法说明
Variant _post_process_key_value(animation: Animation, track: int, value: Variant, object_id: int, object_sub_idx: int) virtual const 🔗
虚函数,用于播放期间在获取关键帧之后的处理。
Error add_animation_library(name: StringName, library: AnimationLibrary) 🔗
将动画库 library
添加至动画播放器中,键名为 name
。
AnimationMixer 默认拥有一个全局库,键名为空字符串。要向这个全局库中添加动画:
var global_library = mixer.get_animation_library("")
global_library.add_animation("animation_name", animation_resource)
手动将动画前进指定的时间(单位为秒)。
void capture(name: StringName, duration: float, trans_type: TransitionType = 0, ease_type: EaseType = 0) 🔗
如果 name
指定的动画轨道具有 Animation.UPDATE_CAPTURE 选项,则会将轨道路径表示的对象当前值存储下来作为缓存。如果已存在捕获缓存,则会丢弃旧缓存。
在此之后,就会在播放过程中进行时长为 duration
的与当前动画混合结果的插值,类似淡入淡出。
可以使用 trans_type
来指定插值曲线。为了达到最佳效果,如果轨道的第一个关键帧非零或键值不会改变,则最好使用 Tween.TRANS_LINEAR;如果键值有线性变化,则最好使用 Tween.TRANS_QUAD。
void clear_caches() 🔗
AnimationMixer 会缓存动画节点。如果一个节点消失,它可能不会注意到;clear_caches() 能够强制它再次更新缓存。
StringName find_animation(animation: Animation) const 🔗
返回 animation
的键;如果未找到,则返回一个空的 StringName。
StringName find_animation_library(animation: Animation) const 🔗
返回包含 animation
的 AnimationLibrary 的键;如果找不到,则返回一个空的 StringName。
Animation get_animation(name: StringName) const 🔗
返回带有键 name
的 Animation。如果动画不存在,则返回 null
并记录错误。
AnimationLibrary get_animation_library(name: StringName) const 🔗
返回第一个键为 name
的 AnimationLibrary,如果没有找到则返回 null
。
要获得 AnimationMixer 的全局动画库,请使用 get_animation_library("")
。
Array[StringName] get_animation_library_list() const 🔗
返回存储库的键名列表。
PackedStringArray get_animation_list() const 🔗
返回存储的动画键列表。
Vector3 get_root_motion_position() const 🔗
获取 root_motion_track 的位置运动增量,这是一个可以在其他地方使用的 Vector3。
如果 root_motion_track 所指向的轨道不是 Animation.TYPE_POSITION_3D 类型,则返回 Vector3(0, 0, 0)
。
另见 root_motion_track 和 RootMotionView。
最基础的示例就是将位置应用到 CharacterBody3D 上:
var current_rotation
func _process(delta):
if Input.is_action_just_pressed("animate"):
current_rotation = get_quaternion()
state_machine.travel("Animate")
var velocity = current_rotation * animation_tree.get_root_motion_position() / delta
set_velocity(velocity)
move_and_slide()
与 get_root_motion_rotation_accumulator() 配合使用就可以将节点的旋转考虑进来,让应用的根运动位置更为准确。
func _process(delta):
if Input.is_action_just_pressed("animate"):
state_machine.travel("Animate")
set_quaternion(get_quaternion() * animation_tree.get_root_motion_rotation())
var velocity = (animation_tree.get_root_motion_rotation_accumulator().inverse() * get_quaternion()) * animation_tree.get_root_motion_position() / delta
set_velocity(velocity)
move_and_slide()
如果 root_motion_local 为 true
,则会返回预先与逆向旋转相乘后的平移值。
此时可以这样编写代码:
func _process(delta):
if Input.is_action_just_pressed("animate"):
state_machine.travel("Animate")
set_quaternion(get_quaternion() * animation_tree.get_root_motion_rotation())
var velocity = get_quaternion() * animation_tree.get_root_motion_position() / delta
set_velocity(velocity)
move_and_slide()
Vector3 get_root_motion_position_accumulator() const 🔗
检索具有 root_motion_track 的位置轨道的混合值,返回的是可以在其他地方使用的 Vector3。
在想要遵循动画的初始动画帧值的情况下很有用。
例如,如果前一帧播放的是一个只有单个动画帧 Vector3(0, 0, 0)
的动画,然后下一帧播放的是一个只有单个动画帧Vector3(1, 0, 1)
的动画,它们之间的差异可以这样计算:
var prev_root_motion_position_accumulator
func _process(delta):
if Input.is_action_just_pressed("animate"):
state_machine.travel("Animate")
var current_root_motion_position_accumulator = animation_tree.get_root_motion_position_accumulator()
var difference = current_root_motion_position_accumulator - prev_root_motion_position_accumulator
prev_root_motion_position_accumulator = current_root_motion_position_accumulator
transform.origin += difference
不过,如果动画是循环播放的,就可能会发生预料之外的不连续变化,所以这只对一些简单的情况有用。
Quaternion get_root_motion_rotation() const 🔗
检索带有 root_motion_track 的旋转运动,作为一个 Quaternion,可以在其他地方使用。
如果 root_motion_track 不是 Animation.TYPE_ROTATION_3D 类型的轨迹的路径,返回 Quaternion(0, 0, 0, 1)
。
另见 root_motion_track 和 RootMotionView。
最基本的例子是对 CharacterBody3D 应用旋转。
func _process(delta):
if Input.is_action_just_pressed("animate"):
state_machine.travel("Animate")
set_quaternion(get_quaternion() * animation_tree.get_root_motion_rotation() )
Quaternion get_root_motion_rotation_accumulator() const 🔗
检索带有 root_motion_track 的旋转轨道的混合值,作为一个 Quaternion,可以在其他地方使用。
这里必须正确地结合根运动位置,并且要考虑到旋转。参考 get_root_motion_position()。
并且,当你想重视动画的初始动画帧的值时,这会很有用。
比如说,如果一个动画在上一帧只播放一个 Quaternion(0, 0, 0, 1)
动画帧,并且一个动画在下一帧只播放了一个动画帧的 Quaternion(0, 0.707, 0, 0.707)
时,它们相差的值可以这样求出:
var prev_root_motion_rotation_accumulator
func _process(delta):
if Input.is_action_just_pressed("animate"):
state_machine.travel("Animate")
var current_root_motion_rotation_accumulator = animation_tree.get_root_motion_rotation_accumulator()
var difference = prev_root_motion_rotation_accumulator.inverse() * current_root_motion_rotation_accumulator
prev_root_motion_rotation_accumulator = current_root_motion_rotation_accumulator
transform.basis *= Basis(difference)
然而,当一个动画循环时,可能会得到一个意料之外的变化,所以这个只在一些简单情况下才有用。
Vector3 get_root_motion_scale() const 🔗
获取 root_motion_track 的缩放运动增量,类型为 Vector3,可以在其他地方使用。
如果 root_motion_track 不是类型为 Animation.TYPE_SCALE_3D 的轨道的路径,则返回 Vector3(0, 0, 0)
。
另见 root_motion_track 和 RootMotionView。
最基本的例子是对 CharacterBody3D 应用缩放。
var current_scale = Vector3(1, 1, 1)
var scale_accum = Vector3(1, 1, 1)
func _process(delta):
if Input.is_action_just_pressed("animate"):
current_scale = get_scale()
scale_accum = Vector3(1, 1, 1)
state_machine.travel("Animate")
scale_accum += animation_tree.get_root_motion_scale()
set_scale(current_scale * scale_accum)
Vector3 get_root_motion_scale_accumulator() const 🔗
检索带有 root_motion_track 的缩放轨道的混合值,作为一个 Vector3,可以在其他地方使用。
例如,如果一个动画在前一帧只播放了一个动画帧 Vector3(1, 1, 1)
,并且一个动画在后一帧只播放了一个动画帧 Vector3(2, 2, 2)
,他们之间相差的值可以这样求出:
var prev_root_motion_scale_accumulator
func _process(delta):
if Input.is_action_just_pressed("animate"):
state_machine.travel("Animate")
var current_root_motion_scale_accumulator = animation_tree.get_root_motion_scale_accumulator()
var difference = current_root_motion_scale_accumulator - prev_root_motion_scale_accumulator
prev_root_motion_scale_accumulator = current_root_motion_scale_accumulator
transform.basis = transform.basis.scaled(difference)
然而,当一个动画循环时,可能会得到一个意料之外的变化,所以这个只在一些简单情况下才有用。
bool has_animation(name: StringName) const 🔗
如果该 AnimationMixer 存有键名为 name
的 Animation,则返回 true
。
bool has_animation_library(name: StringName) const 🔗
如果该 AnimationMixer 存有键名为 name
的 AnimationLibrary,则返回 true
。
void remove_animation_library(name: StringName) 🔗
移除与键 name
关联的 AnimationLibrary。
void rename_animation_library(name: StringName, newname: StringName) 🔗
将与键 name
关联的 AnimationLibrary 移动到键 newname
。