Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Використання Дерева анімації

Вступ

Завдяки AnimationPlayer анімаційна система Godot є одною з найбільш гнучких серед ігрових рушіїв. Можливість анімувати майже будь-яку властивість будь-якого вузла, або ресурсу, а також мати виділені перетворення, криві Безьє, виклики методів, аудіо- та під-анімаційні доріжки, є майже унікальною.

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

AnimationTree (Дерево анімацій) - це новий вузол, представлений в Godot 3.1 для розширення можливих переходів. Він витісняє древній AnimationTreePlayer, додаючи при цьому величезну кількість функцій і гнучкість.

Створення Дерева Анімацій

Спочатку необхідно чітко зрозуміти, що вузол AnimationTree не містить власних анімацій. Замість цього він використовує анімацію, що міститься в вузлі AnimationPlayer. Таким чином, ви можете редагувати свої анімації (або імпортувати їх з 3D-сцени), як зазвичай, а потім використовувати цей додатковий вузол для управління відтворенням.

Найчастіше AnimationTree використовують в 3D-сценах. Імпортовані сцени, як правило, поставляються із вбудованою анімацією (або кількома, або розділеною при імпорті одною великою). В кінці імпортована сцена Godot буде містити анімацію в вузлі AnimationPlayer.

Оскільки ви нечасто використовуєте імпортовані сцени безпосередньо в Godot (вони або вставляються, як екземпляри, або успадковуються), ви можете розмістити вузол AnimationTree у новій сцені, яка містить імпортовану. Після цього вкажіть вузлу AnimationTree вузол AnimationPlayer, що був створений в імпортованій сцені.

Ось як це зроблено в `демонстрації стрілялки від третьої особи<https://github.com/godotengine/tps-demo>`_:

../../_images/animtree1.png

A new scene was created for the player with a CharacterBody3D as root. Inside this scene, the original .dae (Collada) file was instantiated and an AnimationTree node was created.

Створення дерева

Існує три основних типи вузлів, які можна використовувати в AnimationTree:

  1. Animation nodes, which reference an animation from the linked AnimationPlayer.

  2. Анімаційні кореневі вузли, які використовуються для змішування під-вузлів.

  3. Вузли анімації Blend, які використовуються в AnimationNodeBlendTree як один графік змішування з кількох вхідних портів.

Доступні кілька типів кореневих вузлів у AnimationTree:

../../_images/animtree2.png
  • AnimationNodeAnimation: Вибирає анімацію зі списку та відтворює її. Це найпростіший кореневий вузол, і, як правило, не використовується безпосередньо як корінь.

  • AnimationNodeBlendTree: Містить багато вузлів з типом змішування, таких як mix, blend2, blend3, one shot, тощо. Це один з найбільш часто використовуваних коренів.

  • AnimationNodeStateMachine: Містить кілька кореневих вузлів, як дочірніх, на графіку. Кожен вузол використовується як стан і надає кілька функцій для чергування між станами.

  • AnimationNodeBlendSpace2D: Дозволяє розміщувати кореневі вузли в просторі 2D змішування. Керуйте позицією накладання в 2D, щоб змішувати кілька анімацій.

  • AnimationNodeBlendSpace1D: Спрощена версія вищенаведеного (1D).

Дерево змішування

AnimationNodeBlendTree може містити як кореневі, так і звичайні вузли, які використовуються для змішування. Вузли додаються до графіка з меню:

../../_images/animtree3.webp

Всі дерева суміші за замовчуванням містять вузол Output (Вивід), і до нього потрібно підключити щось, щоб анімація відтворювалася.

Найпростіший спосіб протестувати цю функціональність - підключити безпосередньо до нього вузол Animation:

../../_images/animtree4.png

Це просто відтворить анімацію. Для того, щоб щось сталося AnimationTree має бути активним.

Нижче наведено короткий опис доступних вузлів:

Бленд2 / Бленд3

Ці вузли будуть змішувати два, або три, входи за вказаним користувачем значенням змішування:

../../_images/animtree5.gif

Для складнішого змішування рекомендується замість цього використовувати простір для змішування.

При змішуванні також можна використовувати фільтри, тобто ви можете індивідуально контролювати, які доріжки проходять через функцію змішування. Це дуже корисно для накладання анімацій одної на одну.

../../_images/animtree6.png

Одним махом

Цей вузол виконує допоміжну анімацію, а потім повертається до основної. Час сповільнення та прискорення змішування можна налаштувати, як і фільтри.

../../_images/animtree6b.gif

After setting the request and changing the animation playback, the one-shot node automatically clears the request on the next process frame by setting its request value to AnimationNodeOneShot.ONE_SHOT_REQUEST_NONE.

# Play child animation connected to "shot" port.
animation_tree.set("parameters/OneShot/request", AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE)
# Alternative syntax (same result as above).
animation_tree["parameters/OneShot/request"] = AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE

# Abort child animation connected to "shot" port.
animation_tree.set("parameters/OneShot/request", AnimationNodeOneShot.ONE_SHOT_REQUEST_ABORT)
# Alternative syntax (same result as above).
animation_tree["parameters/OneShot/request"] = AnimationNodeOneShot.ONE_SHOT_REQUEST_ABORT

# Get current state (read-only).
animation_tree.get("parameters/OneShot/active"))
# Alternative syntax (same result as above).
animation_tree["parameters/OneShot/active"]

TimeSeek

Цей вузол може бути використаний для команди пошуку будь-яких допоміжних нащадків з анімаційного графіка. Цей тип вузла використовується для відтворення Animation з самого початку, або певної позиції, всередині AnimationNodeBlendTree.

After setting the time and changing the animation playback, the seek node automatically goes into sleep mode on the next process frame by setting its seek_request value to -1.0.

# Play child animation from the start.
animation_tree.set("parameters/TimeSeek/seek_request", 0.0)
# Alternative syntax (same result as above).
animation_tree["parameters/TimeSeek/seek_request"] = 0.0

# Play child animation from 12 second timestamp.
animation_tree.set("parameters/TimeSeek/seek_request", 12.0)
# Alternative syntax (same result as above).
animation_tree["parameters/TimeSeek/seek_request"] = 12.0

ЧасоваШкала

Allows scaling the speed of the animation (or reverse it) connected to the in input via the scale parameter. Setting the scale to 0 will pause the animation.

Перехід

Very simple state machine (when you don't want to cope with a StateMachine node). Animations can be connected to the outputs and transition times can be specified. After setting the request and changing the animation playback, the transition node automatically clears the request on the next process frame by setting its transition_request value to an empty string ("").

# Play child animation connected to "state_2" port.
animation_tree.set("parameters/Transition/transition_request", "state_2")
# Alternative syntax (same result as above).
animation_tree["parameters/Transition/transition_request"] = "state_2"

# Get current state name (read-only).
animation_tree.get("parameters/Transition/current_state")
# Alternative syntax (same result as above).
animation_tree["parameters/Transition/current_state"]

# Get current state index (read-only).
animation_tree.get("parameters/Transition/current_index"))
# Alternative syntax (same result as above).
animation_tree["parameters/Transition/current_index"]

Blend Простір 2D

BlendSpace2D — це вузол для розширеного змішування у двох вимірах. Точки додаються до двовимірного простору, а потім положення можна контролювати, щоб визначити накладання:

../../_images/animtree7.gif

The ranges in X and Y can be controlled (and labeled for convenience). By default, points can be placed anywhere (right-click on the coordinate system or use the add point button) and triangles will be generated automatically using Delaunay.

../../_images/animtree8.gif

Також можна намалювати трикутники вручну, відключивши опцію автоматичного трикутника, хоча це нечасто буває необхідним:

../../_images/animtree9.png

Нарешті, можна змінити режим змішування. За замовчуванням змішування відбувається шляхом інтерполяції точок всередині найближчого трикутника. Коли ви маєте справу з 2D-анімацією (кадр за кадром), ви можете перейти в дискретний режим. Крім того, якщо ви хочете зберегти поточну позицію відтворення під час перемикання між дискретними анімаціями, існує режим Carry. Цей режим можна змінити в меню Змішувати:

../../_images/animtree10.png

Blend Простір 1D

Це схоже на простори 2D-змішування, але в одному вимірі (тому трикутники не потрібні).

Машина стану

Цей вузол діє як машина станів з кореневими вузлами як станами. Кореневі вузли можуть створюватися і з'єднуватися по лініях. Стани з'єднуються через Переходи, які є з'єднаннями зі спеціальними властивостями. Переходи є однонаправленими, але два можуть бути використані для з'єднання в обох напрямках.

../../_images/animtree11.gif

Є багато типів переходів:

../../_images/animtree12.png
  • Негайно: Негайний перехід до наступного стану. Поточний стан завершиться і почнеться новий.

  • Синхронізувати: Переключиться на наступний стан негайно, але буде шукати новий стан до позиції відтворення старого стану.

  • На кінець: Чекатиме завершення відтворення поточного стану, а потім переключиться на початок анімації наступної стану.

Переходи також мають кілька властивостей. Натисніть будь-який перехід, і вони будуть відображатися на панелі інспектора:

../../_images/animtree13.png
  • Switch Mode- це тип переходу (див. вище), його можна змінити після створення тут.

  • Auto Advance ввімкне автоматичний перехід, коли цей стан буде досягнуто. Найкраще працює з режимом перемикача На кінець.

  • Advance Condition ввімкне автоматичне просування вперед, коли буде встановлено цю умову. Це настроюване текстове поле, яке можна заповнити ім'ям змінної. Змінну можна змінити з коду (докладніше про це пізніше).

  • Xfade Time - це час, щоб переходу між цим станом і наступним.

  • Priority використовується разом з функцією travel() з коду (докладніше про це пізніше). Переходи з нижчим пріоритетом мають перевагу під час переходу по дереву.

  • Disabled дозволяє відключити цей перехід (він не буде використовуватися під час переходів, чи автоматичного просування).

For better blending

In Godot 4.0+, in order for the blending results to be deterministic (reproducible and always consistent), the blended property values must have a specific initial value. For example, in the case of two animations to be blended, if one animation has a property track and the other does not, the blended animation is calculated as if the latter animation had a property track with the initial value.

When using Position/Rotation/Scale 3D tracks for Skeleton3D bones, the initial value is Bone Rest. For other properties, the initial value is 0 and if the track is present in the RESET animation, the value of its first keyframe is used instead.

For example, the following AnimationPlayer has two animations, but one of them lacks a Property track for Position.

../../_images/blending1.webp

This means that the animation lacking that will treat those Positions as Vector2(0, 0).

../../_images/blending2.webp

This problem can be solved by adding a Property track for Position as an initial value to the RESET animation.

../../_images/blending3.webp ../../_images/blending4.webp

Примітка

Be aware that the RESET animation exists to define the default pose when loading an object originally. It is assumed to have only one frame and is not expected to be played back using the timeline.

Also keep in mind that the Rotation 3D tracks and the Property tracks for 2D rotation with Interpolation Type set to Linear Angle or Cubic Angle will prevent rotation of more than 180 degrees from the initial value as blended animation.

This can be useful for Skeleton3Ds to prevent the bones penetrating the body when blending animations. Therefore, Skeleton3D's Bone Rest values should be as close to the midpoint of the movable range as possible. This means that for humanoid models, it is preferable to import them in a T-pose.

../../_images/blending5.webp

You can see that the shortest rotation path from Bone Rests is prioritized rather than the shortest rotation path between animations.

If you need to rotate Skeleton3D itself more than 180 degrees by blend animations for movement, you can use Root Motion.

Рух кореня

При роботі з 3D-анімацією популярна техніка полягає в тому, щоб аніматори використовували кореневу кістку скелета, щоб рухати увесь скелет. Це дозволяє анімувати персонажі таким чином, щоб кроки справді відповідали підлозі нижче. Це також дозволяє точно взаємодіяти з об'єктами під час кінематографії.

Під час відтворення анімації в Godot можна вибрати цю кістку як доріжку руху кореня. Це скасує візуальне перетворення кісток (анімація залишиться на місці).

../../_images/animtree14.png

Після цього фактичний рух можна отримати через API AnimationTree, як перетворення:

# Get the motion delta.
animation_tree.get_root_motion_position()
animation_tree.get_root_motion_rotation()
animation_tree.get_root_motion_scale()

# Get the actual blended value of the animation.
animation_tree.get_root_motion_position_accumulator()
animation_tree.get_root_motion_rotation_accumulator()
animation_tree.get_root_motion_scale_accumulator()

This can be fed to functions such as CharacterBody3D.move_and_slide to control the character movement.

Існує також вузол інструменту RootMotionView, який може бути розміщений на сцені і виступати в якості спеціальної підлоги для вашого персонажа та анімації (цей вузол за замовчуванням вимикається під час гри).

../../_images/animtree15.gif

Контроль з коду

Після побудови дерева та його попереднього перегляду залишилося єдине питання: "Як все це контролюється з коду?".

Майте на увазі, що анімаційні вузли є лише ресурсами і, таким чином, вони поділяються між усіма екземплярами. Встановлення значень у вузлах безпосередньо вплине на всі екземпляри сцени, яка використовує це Дерево Анімації AnimationTree. Загалом це не бажано, однак є деякі круті випадки для використання, наприклад, ви можете копіювати та вставляти частини дерева анімації, або повторно використовувати вузли зі складним макетом (наприклад, машина станів, або простір для змішування) у різних анімаційних деревах.

Фактичні дані анімації містяться в вузлі AnimationTree і доступні за допомогою властивостей. Перевірте розділ вузла Parameters, щоб побачити всі параметри, які можна змінити в режимі реального часу:

../../_images/animtree16.png

Це зручно, тому що це дає можливість анімувати їх з``AnimationPlayer`` , або навіть самого AnimationTree, що дозволяє реалізувати дуже складну логіку анімації.

Щоб змінити ці значення з коду, потрібно отримати шлях властивості. Для цього досить навести курсор мишки на будь-який з параметрів:

../../_images/animtree17.png

Маючи шлях можна встановлювати їх, або читати:

animation_tree.set("parameters/eye_blend/blend_amount", 1.0)
# Simpler alternative form:
animation_tree["parameters/eye_blend/blend_amount"] = 1.0

Переходи машини станів

One of the nice features in Godot's StateMachine implementation is the ability to travel. The graph can be instructed to go from the current state to another one, while visiting all the intermediate ones. This is done via the A* algorithm. If there is no path of transitions starting at the current state and finishing at the destination state, the graph teleports to the destination state.

Щоб скористатися переходами, слід спочатку отримати об'єкт AnimationNodeStateMachinePlayback з вузла AnimationTree (він експортується як властивість).

var state_machine = animation_tree["parameters/playback"]

Після отримання його можна використовувати, викликавши одну з багатьох функцій, які він пропонує:

state_machine.travel("SomeState")

Державна машина повинна спочатку запуститися перед відтворенням переходів. Обов'язково викличте start(), або виберіть на вузлі Autoplay on Load.

../../_images/animtree18.png