Анимация в Unity через playables api

Playables API — мощный инструмент, способный сильно облегчить жизнь при анимации в Unity. На начальном этапе Playables API сложен, но при понимании позволяет достигать быстрого результата при анимации и глубокого контроля анимации через код. На официальном сайте есть примеры по использованию Playables, но так как они сложны в понимании и частично устарели, мы разберем простой пример использования на практике.
Лучшей практикой является использование Playable mixer, но так как примеры для новичков сложнее, мы ограничимся базовыми возможностями. Далее приведу пример из практической задачи, в которой требуется запечь позиции костей (осуществить бэйкинг) при проигрывании анимации.
Первым делом нужно создать PlayableGraph. Мы создаем PlayableGraph и немедленно его запустим через вызов playableGraph.Play():
private PlayableGraph playableGraph;
private AnimationClipPlayable clipPlayable; // Тут будем хранить инфу о клипе
private int bakedClipIndex;
private void Start()
{
playableGraph = PlayableGraph.Create();
playableGraph.Play();
}
На данном этапе ничего не произойдет, так как наш playableGraph пустой. Чтобы воспроизводить анимации нам нужно заполнить его данными.
Для получения клипов, предположим, что у нас есть Scriptable класс AnimationSet, который содержит информацию о клипе и ссылку на клип в ресурсах:
public class AnimationSet : ScriptableObject
{
[field: SerializeField] public AnimationClip AnimationClip { get; private set; }
// доп инфа...
}
Далее создадим coroutine который будет:
- Получать информацию о клипе и создавать AnimationClipPlayable
- Создавать AnimationPlayableOutput и передавать в него AnimationClipPlayable
- Симулировать проигрывание анимации, продвигая время на Time.fixedDeltaTime:
private IEnumerator BakeProcess()
{
// тут animator это ссылка на Unity animator на вашем персонаже
var playableOutput = AnimationPlayableOutput.Create(playableGraph, "AnimationsBaker", animator);
// создаем clipPlayable получая ссылку на клип animationSet.AnimationClip
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;
}
}
Пример упрощен, к примеру, тут нет поля для указания ссылки на аниматор и не показано, как мы получаем набор клипов, так как это не входит в область данного урока. Я постарался показать, как с помощью нескольких строк кода Playables API можно воспроизвести клип и управлять временем его воспроизведения.