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) 🔗
Notifies when an animation starts playing.
Note: This signal is not emitted if an animation is looping.
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 時,前兩者具有優先權。這是 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,結果等同 AnimationNodeBlend2 權重為 0.5。
此功能由編輯器使用。若設為 true,場景將以重設動畫(鍵為 "RESET" 的動畫)在時間 0 的狀態儲存,編輯器也會保留儲存前的場景值。
這讓在編輯器中預覽與編輯動畫更方便,只要變更寫在重設動畫中,就不會被存入場景。
bool root_motion_local = false 🔗
若為 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。