AnimationMixer

Наследует: Node < Object

Наследуется от: AnimationPlayer, AnimationTree

Базовый класс для AnimationPlayer и AnimationTree.

Описание

Базовый класс для AnimationPlayer и AnimationTree для управления списками анимации. Он также имеет общие свойства и методы для воспроизведения и смешивания.

После создания экземпляра данных информации о воспроизведении в расширенном классе, смешивание и обработка происходит в AnimationMixer.

Обучающие материалы

Свойства

bool

active

true

int

audio_max_polyphony

32

AnimationCallbackModeDiscrete

callback_mode_discrete

1

AnimationCallbackModeMethod

callback_mode_method

0

AnimationCallbackModeProcess

callback_mode_process

1

bool

deterministic

false

bool

reset_on_save

true

bool

root_motion_local

false

NodePath

root_motion_track

NodePath("")

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)

void

advance(delta: float)

void

capture(name: StringName, duration: float, trans_type: TransitionType = 0, ease_type: EaseType = 0)

void

clear_caches()

StringName

find_animation(animation: Animation) const

StringName

find_animation_library(animation: Animation) const

Animation

get_animation(name: StringName) const

AnimationLibrary

get_animation_library(name: StringName) const

Array[StringName]

get_animation_library_list() const

PackedStringArray

get_animation_list() const

Vector3

get_root_motion_position() const

Vector3

get_root_motion_position_accumulator() const

Quaternion

get_root_motion_rotation() const

Quaternion

get_root_motion_rotation_accumulator() const

Vector3

get_root_motion_scale() const

Vector3

get_root_motion_scale_accumulator() const

bool

has_animation(name: StringName) const

bool

has_animation_library(name: StringName) const

void

remove_animation_library(name: StringName)

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 интерполируются между кодами символов и длинами, но обратите внимание, что есть разница в алгоритме между интерполяцией между ключами и интерполяцией путем смешивания.


Описания свойств

bool active = true 🔗

  • void set_active(value: bool)

  • bool is_active()

Если true, AnimationMixer будет выполнять обработку.


int audio_max_polyphony = 32 🔗

  • void set_audio_max_polyphony(value: int)

  • int get_audio_max_polyphony()

Количество возможных одновременных звуков для каждого из назначенных AudioStreamPlayers.

Например, если это значение равно 32 и анимация имеет две аудиодорожки, два назначенных AudioStreamPlayer могут одновременно воспроизводить до 32 голосов каждый.


AnimationCallbackModeDiscrete callback_mode_discrete = 1 🔗

Обычно дорожки можно установить на Animation.UPDATE_DISCRETE для редкого обновления, обычно при использовании ближайшей интерполяции.

Однако при смешивании с Animation.UPDATE_CONTINUOUS рассматриваются несколько результатов. callback_mode_discrete указывает это явно. См. также AnimationCallbackModeDiscrete.

Чтобы смешанные результаты выглядели хорошо, рекомендуется установить это на ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS для обновления каждого кадра во время смешивания. Существуют другие значения для совместимости, и они хороши, если смешивания нет, но не так, могут создавать артефакты.


AnimationCallbackModeMethod callback_mode_method = 0 🔗

Режим вызова, используемый для треков «Вызов Метода».


AnimationCallbackModeProcess callback_mode_process = 1 🔗

Уведомление о процессе, в котором необходимо обновить анимацию.


bool deterministic = false 🔗

  • void set_deterministic(value: bool)

  • bool is_deterministic()

Если 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.


bool reset_on_save = true 🔗

  • void set_reset_on_save_enabled(value: bool)

  • bool is_reset_on_save_enabled()

Это используется редактором. Если установлено значение true, сцена будет сохранена с эффектами анимации сброса (анимация с ключом "RESET"), примененными так, как если бы она была перенесена на время 0, при этом редактор сохраняет значения, которые сцена имела до сохранения.

Это делает более удобным предварительный просмотр и редактирование анимаций в редакторе, поскольку изменения в сцене не будут сохранены, пока они установлены в анимации сброса.


bool root_motion_local = false 🔗

  • void set_root_motion_local(value: bool)

  • bool is_root_motion_local()

Если 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 advance(delta: float) 🔗

Вручную продвиньте анимацию на указанное время (в секундах).


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.