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_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_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 🔗
Количество возможных одновременных звуков для каждого из назначенных 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, при этом редактор сохраняет значения, которые сцена имела до сохранения.
Это делает более удобным предварительный просмотр и редактирование анимаций в редакторе, поскольку изменения в сцене не будут сохранены, пока они установлены в анимации сброса.
bool root_motion_local = false 🔗
Если true, значение get_root_motion_position() извлекается как локальное значение перевода перед смешиванием. Другими словами, оно обрабатывается так, как будто перевод выполняется после поворота.
NodePath root_motion_track = NodePath("") 🔗
Путь к дорожке анимации, используемой для корневого движения. Пути должны быть допустимыми путями дерева сцены к узлу и должны быть указаны, начиная с родительского узла узла, который будет воспроизводить анимацию. Member 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 🔗
Возвращает ключ для AnimationLibrary, содержащий animation, или пустой StringName, если он не найден.
Animation get_animation(name: StringName) const 🔗
Возвращает Animation с ключом name. Если анимация не существует, возвращается null и регистрируется ошибка.
AnimationLibrary get_animation_library(name: StringName) const 🔗
Возвращает первую AnimationLibrary с ключом name или 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 🔗
Извлеките смешанное значение треков вращения с memberroot_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 🔗
Возвращает true, если AnimationMixer хранит Animation с ключом name.
bool has_animation_library(name: StringName) const 🔗
Возвращает true, если AnimationMixer хранит AnimationLibrary с ключом name.
void remove_animation_library(name: StringName) 🔗
Удаляет AnimationLibrary, связанный с ключом name.
void rename_animation_library(name: StringName, newname: StringName) 🔗
Перемещает AnimationLibrary, связанный с ключом name, в ключ newname.