Думаю, многим, кто работает с Unity, приходилось работать с анимациями. После кропотливой работы с аниматором, на выходе получалось такое:

Дикий ужас
Дикий ужас

Для меня осталось загадкой, почему Playables API остался без обзоров и туториалов, и я постарался это исправить. Playables API - это мощный инструмент для работы с анимацией в Unity, который предлагает ряд преимуществ по сравнению с традиционными методами анимации:

  • Управление временем

  • Playables API позволяет вам программно управлять анимацией

  • API Playables позволяет динамически смешивать анимации

  • PlayableGraph можно создать во время выполнения вместо того, чтобы иметь огромный «универсальный» аниматор

PlayableGraph - это сердце Playables API в Unity. Представьте его как "сцена" или "полотно", на котором вы располагаете и связываете разные Playable-объекты, чтобы создать сложную анимацию.

К Playables API я прибегнул при решении конкретной задачи, разрабатывая решение для создания сетевых детерминированных файтингов на Unity. Нужно было получить производительный и гибкий инструмент для:

- Рендера просчитанной анимации

- Запекания позиций костей на всей продолжительности анимационных клипов

Я не буду вдаваться в подробности просчета времени анимаций/переходов, а сфокусируюсь только на воспроизведении клипов и основных вызовах API.

Преимущество подхода

Начнем с того что Playables позволяет нам вынести клипы в аккуратный ScriptableObject:

Который в свою очередь содержит наборы scriptableobject с информацией наших "анимациях":

Запекание анимации (позиций костей)

Данный пример проще для разбора, так как использует базовые возможности api. Для понимания технической стороны запекания:

  • В костях персонажа создаются якоря
  • Симулируем воспроизведение клипа
  • Получаем и записываем данные

1 и 3 пункты мы опустим, так как они не имеют отношения к api. Рассмотрим воспроизведение:

Первым делом нужно создать PlayableGraph. Создаем PlayableGraph и запустим при старте через вызов playableGraph.Play():

private PlayableGraph playableGraph; private AnimationClipPlayable clipPlayable; private int bakedClipIndex; private void Start() { playableGraph = PlayableGraph.Create(); playableGraph.Play(); }

AnimationClipPlayable - это один из основных типов Playable-объектов в Playables API, который непосредственно управляет воспроизведением анимации, хранящейся в AnimationClip.

На данном этапе ничего не произойдет, так как наш PlayableGraph пустой. Чтобы воспроизводить анимации, нам нужно заполнить его данными. Для получения клипа обратимся к scriptableobject с изображения выше:

public class AnimationSet : ScriptableObject { [field: SerializeField] public AnimationClip AnimationClip { get; private set; } //... }

Далее создадим coroutine который будет:

  • Получать информацию о клипе и создавать AnimationClipPlayable
  • Создавать AnimationPlayableOutput и передавать в него AnimationClipPlayable
  • Симулировать проигрывание анимации, продвигая время на Time.fixedDeltaTime

AnimationPlayableOutput - это как "мостик", который связывает вашу анимацию, управляемую Playables API, с реальным объектом в игре, который будет анимироваться.

private IEnumerator BakeProcess() { // Тут animator это ссылка на Unity animator на вашем персонаже var playableOutput = AnimationPlayableOutput.Create(playableGraph, "AnimationsBaker", animator); // Создаем clipPlayable получая ссылку на клип animationSet.AnimationClip // В реальной задаче я прохожусь по всем animationSet используя bakedClipIndex clipPlayable = AnimationClipPlayable.Create(playableGraph, animationSet.AnimationClip); playableOutput.SetSourcePlayable(clipPlayable); // задаем clipPlayable в playableOutput // Время анимации double currentTime = 0f; while (true) { currentTime += Time.fixedDeltaTime; // Именно SetTime отвечает за проигрывание клипа, продвигая его время на currentTime clipPlayable.SetTime(currentTime); // Получение позиции якорей и запись данных // Если достигли длины клипа можем брать след. клип if (currentTime >= animationSet.AnimationClip.length) { bakedClipIndex++; StartCoroutine(BakeProcess()); break; } yield return null; } }

Стоит отметить, что данный функционал возможно реализовать используя возможности API аниматора, но Playables дает больше возможностей, гибкости и, как заявлено, производительности. Если данная тема востребована, в следующей части мы рассмотрим продвинутый пример использования Playables для анимации персонажа, который не уступает по функционалу обычному аниматору.

Мой канал в телеграмм Unity Show-Off для поиска вдохновения. Мой блог.

1717
11
9 комментариев

Playables всегда интересовали, и по ним трудно найти какие–то уроки, но на картинке показано неправильное использование стандартного аниматора юнити. Далеко не для всех стейтов нужно делать прямые переходы, многие можно (и нужно) вызывать напрямую. Но все рекомендуют переходить на Animancer, который как раз на Playables и сделан. Сам я как–то более–менее пока обхожусь стандартным аниматором, хоть и понимаю как много вещей сделаны неудобно

5
Ответить

В Unity есть возможность настраивать анимацию исключительно через код? Т.е. полностью без их редактора анимаций?

1
Ответить
Автор

Ну да в этом и суть

Ответить

В редакторе анимаций и не настраивают персонажные анимации. Он для всяких перемещений объектов, кнопок, иконок и тд. Но в целом, там хорошее подспорье для анимаций безкостевых объектов, которые можно делать прям в движке.

Ответить

Комментарий недоступен

Ответить

Playables, это хорошо, но нужно понимать, что когда начинаешь их использовать залезаешь в низкоуровневую систему и нужно много настраивать самому. При этом могут вылезти баги, если что-то не предусмотрел или не знаешь. Т.е. это не так, что включил и оно работает. У меня, например, не сбрасывались состояния в AnimationClip, когда я работал с Playables, а в стандартном анимационном контроллере сбрасываются, поэтому анимационные клипы могут не работать в обоих случаях. В общем, я бы не стал советовать эту систему, пока не попробуешь стандартный подход с анимациями, а точнее играть их через Play(), напрямую. Возможно даже, если использовать граф, то переходов будет не так сильно и все будет лучше, чем тратить время на создания своей системы на Playables, которую нужно потом будет допиливать. В общем, есть пакет Animancer (как уже упомянули в комментариях), его автор очень много отвечает на вопросы по Playbles и не советует их использовать без необходимости, точнее если хотите сделать свой AnimationController, пожалуйста, а если хотите заниматься игрой, то лучше взять что-нибудь готовое. С другой стороны Playables очень хорошо работают, когда у вас кастомная машина состояний или дерево поведения, в общем туда, где вам нужна анимация и чтобы это еще можно настраивать из кода, но это уже для крупных проектов.

Ответить
Автор

А почему в итоге состояние не сбрасывалось?

Ответить