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.INTERPOLATION_NEAREST 混合时,始终将 Animation.UPDATE_DISCRETE 轨道值视为 Animation.UPDATE_CONTINUOUS。这是 AnimationTree 的默认行为。
如果值轨道具有非数字类型键值,则在和 Animation.UPDATE_DISCRETE 混合时,会在内部转换为使用 ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE。
属性说明
如果 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 一样,编辑器保留场景在保存之前的值。
这使得在编辑器中预览和编辑动画更加方便,因为对场景的更改,只要在重置动画中被设置,就不会被保存。
NodePath root_motion_track = NodePath("")
🔗
The path to the Animation track used for root motion. Paths must be valid scene-tree paths to a node, and must be specified starting from the parent node of the node that will reproduce the animation. The root_motion_track uses the same format as Animation.track_set_path, but note that a bone must be specified.
If the track has type Animation.TYPE_POSITION_3D, Animation.TYPE_ROTATION_3D, or Animation.TYPE_SCALE_3D the transformation will be canceled visually, and the animation will appear to stay in place. See also get_root_motion_position, get_root_motion_rotation, get_root_motion_scale, and 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) 🔗
Adds library
to the animation player, under the key name
.
AnimationMixer has a global library by default with an empty string as key. For adding an animation to the global library:
GDScript
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:
GDScript
var current_rotation: Quaternion
func _process(delta):
if Input.is_action_just_pressed("animate"):
current_rotation = get_quaternion()
state_machine.travel("Animate")
var velocity: Vector3 = current_rotation * animation_tree.get_root_motion_position() / delta
set_velocity(velocity)
move_and_slide()
通过将其与 get_root_motion_position_accumulator 结合使用,你可以更正确地应用根运动位置来考虑节点的旋转。
GDScript
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: Vector3 = (animation_tree.get_root_motion_rotation_accumulator().inverse() * 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)
的动画,它们之间的差异可以这样计算:
GDScript
var prev_root_motion_position_accumulator: Vector3
func _process(delta):
if Input.is_action_just_pressed("animate"):
state_machine.travel("Animate")
var current_root_motion_position_accumulator: Vector3 = animation_tree.get_root_motion_position_accumulator()
var difference: Vector3 = 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 应用旋转。
GDScript
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 🔗
Retrieve the blended value of the rotation tracks with the root_motion_track as a Quaternion that can be used elsewhere.
This is necessary to apply the root motion position correctly, taking rotation into account. See also get_root_motion_position.
Also, this is useful in cases where you want to respect the initial key values of the animation.
For example, if an animation with only one key Quaternion(0, 0, 0, 1)
is played in the previous frame and then an animation with only one key Quaternion(0, 0.707, 0, 0.707)
is played in the next frame, the difference can be calculated as follows:
GDScript
var prev_root_motion_rotation_accumulator: Quaternion
func _process(delta):
if Input.is_action_just_pressed("animate"):
state_machine.travel("Animate")
var current_root_motion_rotation_accumulator: Quaternion = animation_tree.get_root_motion_rotation_accumulator()
var difference: Quaternion = 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)
However, if the animation loops, an unintended discrete change may occur, so this is only useful for some simple use cases.
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 应用缩放。
GDScript
var current_scale: Vector3 = Vector3(1, 1, 1)
var scale_accum: Vector3 = 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)
,他们之间相差的值可以这样求出:
GDScript
var prev_root_motion_scale_accumulator: Vector3
func _process(delta):
if Input.is_action_just_pressed("animate"):
state_machine.travel("Animate")
var current_root_motion_scale_accumulator: Vector3 = animation_tree.get_root_motion_scale_accumulator()
var difference: Vector3 = 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
。