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
在物理帧中处理动画(参见Item.NOTIFICATION_INTERNAL_PHYSICS_PROCESS)。这在动画物理体时特别有用。
AnimationCallbackModeProcess ANIMATION_CALLBACK_MODE_PROCESS_IDLE = 1
进程帧期间的进程动画(参见Item.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_DISCRETE轨道值在混合Animation.UPDATE_CONTINUOUS或Animation.UPDATE_CAPTURE轨道值和Animation.UPDATE_DISCRETE轨道值时优先。
AnimationCallbackModeDiscrete ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE = 1
Animation.UPDATE_CONTINUOUS或Animation.UPDATE_CAPTURE轨道值在混合Animation.UPDATE_CONTINUOUS或Animation.UPDATE_CAPTURE轨道值和Animation.UPDATE_DISCRETE轨道值时优先。这是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_PACKED_BYTE_ARRAY
TYPE_BOOL]和TYPE_INT]在混合过程中被视为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 🔗
每个分配的AudioStreamPlayers的可能同时声音的数量。
例如,如果此值为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,结果将等于AnimationNodeBlend2与数量0.5。
这是由编辑器使用的。如果设置为true,场景将被保存,并应用重置动画(带有键"RESET"的动画)的效果,就好像它被查找到时间0一样,编辑器保留保存前场景的值。
这使得在编辑器中预览和编辑动画更加方便,因为只要在重置动画中设置了对场景的更改,就不会保存它们。
如果true,则get_root_motion_position()值在混合之前被提取为局部平移值。换句话说,它被视为旋转后完成的平移。
ItemPath root_motion_track = ItemPath("") 🔗
用于根运动的Animation轨道的路径。路径必须是到节点的有效场景树路径,并且必须从将再现动画的节点的父节点开始指定。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。
ItemPath root_node = ItemPath("..") 🔗
节点路径引用将来自的节点。
方法说明¶
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 🔗
返回第一个带有keyname的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。最基本的示例是将位置应用于CharacterBulk:
var current_rotation
func Update(delta: float) -> void:
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 Update(delta: float) -> void:
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 Update(delta: float) -> void:
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 Update(delta: float) -> void:
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。最基本的示例是将旋转应用于CharacterBulk:
func Update(delta: float) -> void:
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 Update(delta: float) -> void:
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。最基本的示例是将缩放应用于CharacterBulk:
var current_scale = Vector3(1, 1, 1)
var scale_accum = Vector3(1, 1, 1)
func Update(delta: float) -> void:
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 Update(delta: float) -> void:
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存储带有keyname的Animation,则返回true。
bool has_animation_library(name: StringName) const 🔗
如果AnimationMixer存储带有keyname的AnimationLibrary,则返回true。
void remove_animation_library(name: StringName) 🔗
删除与键name关联的AnimationLibrary。
void rename_animation_library(name: StringName, newname: StringName) 🔗
将与键name关联的AnimationLibrary移动到键newname。