Как сделать 2D-анимацию в Unity с минимумом кода: кадры и скрипты
Инди-играм может не хватать визуальной привлекательности. Разбираемся, как оживить персонажей и фоны с помощью самой простой анимации.


vlada_maestro / shutterstock
Что можно анимировать в Unity
Анимация позволяет оживить игру даже с самой примитивной графикой. Например, персонаж для игры из этой статьи выглядит вот так:

В нём нет ничего привлекательного, это набор простых фигур. Посмотрите, как он изменится, если добавить анимацию:

Теперь персонаж стал чуть более живым и даже забавным — на него гораздо приятнее смотреть, хотя внешне он не изменился.
С помощью анимации можно оживить и фоны. Например, сделать:
- качающиеся волны;
- блики небоскрёбов;
- загорающиеся и гаснущие окна домов;
- мерцающие звёзды и так далее.
Анимацию добавляют и в интерфейсы: переливающиеся шкалы здоровья, поблёскивающие кнопки. Даже вращающаяся шестерёнка вместо простой надписи «Загрузка…» украсит проект.

Мини-игра к этой статье и все ассеты выложены в репозитории на GitHub. Если хотите научиться делать игры с нуля, рекомендуем записаться на курс «Профессия разработчик игр на Unity».
Анимация «из коробки» в Unity
В Unity создают анимацию с помощью:
- скриптов;
- кадров;
- скелетов.
Скрипт изменяет параметры объекта при определённых условиях: обновлении масштабов, добавлении цвета и так далее.
Что-то более продвинутое делается с помощью покадровой анимации — когда для разных состояний объекта (стоит, идёт, в прыжке, атакует) создаётся несколько спрайтов (двумерных изображений), которые сменяют друг друга с определённым интервалом.
И чуть более сложное — скелеты. Они позволяют использовать один спрайт, а потом приводить его в движение, изменяя положение отдельных частей.
Мы рассмотрим только скриптовую и покадровую анимацию в Unity, потому что для скелетной требуются специальные ассеты, и она куда сложнее.
Анимация вращения с помощью скрипта в Unity
Когда вы создаёте персонажа и добавляете ему спрайт, а потом управляете им, герой всегда смотрит в одну и ту же сторону, даже если движется в другую.
Исправить, создав отзеркаленную версию спрайтов, — не лучший вариант, потому что придётся делать лишнюю работу. Правильнее написать скрипт, который вращает объект.
Сначала в Character.cs добавим поле:
public bool isRightSide = true; //Если true, персонаж смотрит направо, а иначе — налево
Затем создаём метод, который вращает спрайт:
void Spin()
{
isRightSide = !isRightSide;
transform.localScale = new Vector3(transform.localScale.x * -1, 1f, 1f);
}
Он принимает направление движения и меняет масштаб по оси X. Умножив его на –1, можно «перевернуть» объект.
Затем в Update () прописывается вызов метода Spin ():
float moveX = Input.GetAxis("Horizontal"); //Получение направления движения
Rigidbody2D rb = GetComponent<Rigidbody2D>(); //Получение компонента, ответственного за физику объекта. Чтобы снизить нагрузку на игру, получение Rigidbody2D лучше вынести в метод Start().
rb.MovePosition(rb.position + Vector2.right * moveX * speed * Time.deltaTime); //Движение
if((moveX > 0f && !isRightSide) || (moveX < 0f && isRightSide)) { //Если игрок начал двигаться в противоположную сторону
if (moveX != 0f) //Если он не стоит
{
Spin (); //Вызов метода Spin()
}
}
Теперь персонаж будет менять направление:

Подготовка спрайтов для анимации в Unity
Чтобы работать с покадровой анимацией, создаём по набору спрайтов для каждого состояния игрока:
- Idle — стоит;
- Run — идёт или бежит;
- Jump — в прыжке;
- Attack — атакует.
Спрайты должны немного отличаться друг от друга, чтобы было заметно движение.
Например, для состояния Idle:

Подвигайте персонажа в Photoshop и сохраните каждый кадр как отдельный файл. Старайтесь давать имена, по которым поймёте шаг анимации: Robot_Idle1.png, Robot_Attack2.png и так далее.
Для каждого состояния лучше создать отдельную папку, чтобы было удобнее работать со спрайтами.
Добавление анимации
Готовые спрайты добавьте в папку с ассетами. Затем выберите в списке с объектами персонажа и зайдите в меню Window — Animation.
Дальше нажмите Create и выберите путь сохранения анимации. Желательно сохранять все анимации в отдельную папку. Сам файл можно назвать Character_Idle.anim или Character_Jump.anim. Первая часть соответствует названию объекта, а вторая — состоянию.
Перетащите необходимые спрайты на временную шкалу.

Теперь запускаем анимацию кнопкой Play. Так как кадров мало, они меняются слишком быстро. Чтобы это исправить, измените значение Samples. По умолчанию установлено 60, но попробуйте поставить 12, 6, 3 или любое другое значение.
Вот как выглядит такая анимация в игре:

Таким же способом создайте анимацию и для других состояний: Run, Jump, Attack.
Управление переходами
Теперь сделаем так, чтобы анимация менялась вместе с состоянием объекта.
Например, если игрок нажмёт на кнопку атаки, персонаж должен не только выпустить снаряд, но и изменить свою анимацию. Чтобы управлять сменой состояний, используются переходы из Animator или Animation Controller. Он автоматически появился в той же папке, в которую сохранена анимация.

Чтобы запустить его, зайдите в меню Window — Animator. Вот как выглядит этот файл:

Изначально в нём уже собраны все созданные анимации, но не установлены связи. Чтобы добавить их, используйте переходы.
Первый переход находится между состояниями Entry и Character_Idle — это анимация, воспроизводимая по умолчанию.
Exit задает анимацию, которая появится перед смертью героя. А Any State — переход из любого состояния, он значительно сократит количество компонентов Transition.
Перед созданием переходов добавьте параметры, которые будут использоваться в условиях. Для этого нажмите на Parameters, затем на кнопку с плюсом и выберите тип:

Теперь добавим сами переходы. Нажмите на любое состояние правой кнопкой мыши и выберите Make Transition. Затем проведите стрелку на любую другую анимацию.
Потом нажмите на стрелку, чтобы указать условия в поле Conditions.

Тут указано, что переход будет совершён, если персонаж на земле и если его скорость больше 0,1. Такое маленькое значение установлено, чтобы анимация реагировала даже при незначительных изменениях.
Таким же образом пропишите условия и переходы для остальных состояний.
По умолчанию параметры никак не меняются — их обновление прописывают с помощью скриптов. Для этого зайдите в Character.cs и добавьте поле animator:
public Animator animator;
После этого в редакторе Unity перетащите компонент Animator в поле animator компонента Character.cs.
Теперь можно работать с аниматором с помощью скрипта. Например, в методе Update () в качестве скорости передаётся направление движения:
float moveX = Input.GetAxis("Horizontal");
rb.MovePosition(rb.position + Vector2.right * moveX * speed * Time.deltaTime);
animator.SetFloat("Speed", Math.Abs(moveX)); //Будет передано только положительное значение
Так же и другие параметры — isLanded меняется в методе Jump ():
void Jump() //Метод прыжка
{
if(isLanded) //Можно прыгнуть, только если персонаж на земле
{
rb.AddForce(Vector2.up * jumpForce); //Добавление силы прыжка
isLanded = false;
animator.SetBool("IsLanded", isLanded); //Изменение параметра
}
}
Сделав всё то же самое со всеми параметрами, запустим игру и проверим, как всё работает. Вот так наш персонаж ходит:

А вот он стреляет:

Так мы сделали простую анимацию для игры, написав минимум кода.
Заключение
Это небольшая часть встроенных возможностей Unity для работы с анимацией. Более подробно вы изучите их на курсе «Профессия разработчик игр на Unity», где работа строится на реальных проектах.