Проблемы покадровой анимации в Unity и как их быстро решить

Покадровая анимация на спрайтах в Unity из коробки — это весело.

Проблемы покадровой анимации в Unity и как их быстро решить

Весело, конечно же, из-за встроенного в Unity аниматора, который часто пытаются использовать с ней. В каком-то смысле он слишком умный. Он отлично подойдёт для костной анимации и вообще, чего угодно, но не для кадровой анимации. Даже если всё-таки создать контроллер, импортировать правильно ассеты и настроить правильно клипы, то встреча с этой гигантской стейт-машиной, которая вынуждает писать очень странную и не всегда вразумительную логику в скриптах всё равно неизбежна.

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

  • сложный механизм клипов;

  • не менее сложный механизм транзакций;

  • невозможность «подменять» спрайты для скинов или просто универсальных контроллеров.

Про это ужасно много разных видео и статей, но я расскажу про самый тривиальный способ написать свой «велосипед» анимации, которым обычно пользуюсь сам. Сразу скажу, что каких-то открытий тут не будет, это лишь занимательная заметка.

Хранение анимации

Прежде всего, нужно создать объект, который будет хранить кадры анимации. Ничего особо не придумывая, я создал предельно простой scriptable-объект.

public class SpritesLine : ScriptableObject { public Sprite[] sprites; }

Чтобы каждый раз не собирать спрайты по одному руками, я сделал не менее простой скрипт для создания скриптового объекта.

public class SpriteLineCreating : MonoBehaviour { [MenuItem("Assets/Create/Sprites line")] public static void CreateSpritesLine() { var asset = ScriptableObject.CreateInstance<SpritesLine>(); var sprites = new List<Sprite>(); foreach (var selected in Selection.objects) { if (selected is Sprite s) { sprites.Add(s); } } asset.sprites = sprites.ToArray(); ProjectWindowUtil.CreateAsset(asset, "Sprite Line.asset"); } }

Теперь достаточно выделить несколько спрайтов, нажать правую кнопку мыши и выбрать Sprite Line. Всё предельно просто.

Осталось прикрутить это всё к самим объектам.

Аниматор

Создадим компонент, который будет устанавливать спрайты в SpriteRenderer. Я не буду расписывать каждый кусок кода — просто выложу на него ссылку, там достаточно много комментариев. Ещё там лежит кастомный инспектор для удобства. Тут выделю просто важные моменты.

Во-первых, я сделал переменную _revalidate, чтобы не слишком часто дёргать SpriteRenderer. Если этого не делать, скрипт будет постоянно обращаться к полю sprite и постоянно подгуружать связанные с полем объекты. Чтобы это возымело какой-то эффект, на сцене должно быть несколько тысяч спрайтов, но лично мне так спокойнее. Лично у меня на M1 при 10 тысячах спрайтов в редакторе _revalidate стало вопросом 20 FPS.

Во-вторых, спрайт задается в LateUpdate. Это довольно важная деталь, чтобы можно было спокойно менять параметры из других скриптов и не переживать, что Update нашего аниматора вызовется до этого момента.

Вообще, аниматор получился ужасно простым, и его легко доделывать под нужные вещи. Я, например, добавил ивент для окончания анимации, чтобы разрушать объекты, которые представляют просто эффекты. Выглядит в редакторе это тоже максимально простенько, но ведь не часто нужно что-то большее.

Проблемы покадровой анимации в Unity и как их быстро решить

Велосипеды — это плохо

Очевидно, что не всем нравится писать «велосипеды», и хочется что-то поддерживаемое. Относительно недавно (полгода как не в эксперименте, если быть точным) в Unity появился инструментарий для подмены спрайтов в клипах с поддержкой покадровой анимации. От аниматора уйти это не позволяет, но вводит инструментарий для всего, что описано выше. Если вам всё-таки нравится аниматор или просто тяжело с него слезать — это, возможно, ваш выбор.

Другой занимательный пример, который я видел, — это ReAnimator. Это довольно навороченный инструмент с поддержкой событий на кадры, синхронизации частоты кадров и хитрой системы переходов.

Очевидно, что тут в посте нет каких-то сакральных и неизвестных вещей. Тем не менее не все сразу отказываются от аниматора, видя множество туториалов с ним. Да и про его аналоги не всем известно. Так что, буду надеяться, эти заметки станут кому-то полезными в том или ином виде.

66
17 комментариев