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.