Создание игры на ваших глазах — часть 7: 2D-анимации в Unity («как во флэше»)
В этой статье поговорим о 2D анимациях в Unity. Я расскажу о своем опыте работы с родными анимациями в юнити, о том, насколько тайм-лайны похожи на флэшевские, об управлении анимациями, event’ах, вложенности, и о том, как художник справляется с анимированием.
Для начала, немного теории.
В Unity есть две сущности:
1. Анимация (то, что отображается в окно «Animation»)
2. Mechanim дерево анимаций (то, что отображается в окне «Animator»).
Ниже я немного расскажу, что это такое и как нам может приходиться (или не пригодиться).
Animation
Итак, анимация. По сути — это таймлайн с ключевыми кадрами. Здесь вы можете двигать, поворачивать, масштабировать ваши объекты. Естественно, можно рисовать кривые и пользоваться разными изингами. И даже управлять любыми (в т.ч. самописными) их свойствами. То есть вполне можно написать компонент с float паблик-значением «яркость» и эту самую «яркость» анимировать наравне с x, y, z штатными средствами. Спрайты поддерживают покадровую анимацию.

Кстати, несмотря на то, что у каждой анимации есть FPS (поле «sample»), сами анимации к FPS не привязаны. Они привязаны ко времени. Т.е. если вы делаете анимацию с 5 FPS, где у вас объект двигается из точки А в точку Б с помощью задания двух ключевых кадров в начале и в конце, то в игре этот объект не будет двигаться ступеньками с 5 FPS. Анимация рассчитывается каждый кадр игры, а FPS внутри анимации сделан лишь для вашего удобства, чтобы вам не частить кадры.
Animator
Это — большая и сложная система, которая непосредственно управляет анимациями. То есть анимация — это просто файл (ресурс) с настройками ключевых кадров и сама по себе ничего не умеет. Вот именно компонент «Animator» — это то, что умеет играть эти анимации.
Кроме того, вы можете создавать дерево этих анимаций с морфингом между ними. Т.е. если у вас есть персонаж, анимированный перекладками (когда каждая часть тела — отдельный спрайтик, который вы вращаете/двигаете), то вполне можно сделать анимацию ног отдельно, анимацию рук — отдельно. А потом (с помощью мышки) настроить условие, что от скорости движения вашего объекта, mechanim аниматор будет включать либо анимацю ног «ходьба», либо «бег». А стрелять ваш персонаж будет отдельной анимацией, которая никак не связана со скоростью переставления ног.
В самом же просто случае, ваш аниматор будет выглядеть так:

то есть содержать одну-единственную анимацию и никаких связей/переходов.
Начинаем шаманить.
Пока все понятно. Но давайте подумаем, как сделать что-то чуть более сложное?
Мой конкретный случай — у нас есть сугроб снега, в котором сидит заяц. Сугроб сам по себе шевелится:
Далее, мы хотим сделать такую анимацию:

1. сугроб, шевелясь, двигается влево
2. из сугроба выглядывает заяц (анимация пульсации останавливается):
3. сугроб двигается вправо
В принципе, ничего сложного. Анимируем пульсацию сугроба внутри объекта, внешним аниматором двигаем его влево, потом скрываем, вместо него показываем покадровую анимацию выглядывающего зайца, потом обратно. И все это на одном таймлайне (кроме «внутренней» анимации сугроба).
Но такой вариант мне не нравится его жесткостью. В первую очередь я считаю неправильным, что в таком варианте покадровая анимация вылезающего кролика оказывается на том же таймлайне, что и движение сугроба. Это значит, что если мы захотим сделать вариацию этой анимации, где сугроб будет двигаться по другой траектории, мы должны будем заново анимировать вылезание зайца. А если мы потом это самое вылезание захотим поправить, то нам придется делать это во всех анимациях, где оно используется.
Хотелось бы большей гибкости.
Есть другой вариант. Мы анимируем выглядывание зайца в отдельном объекте (так же, как мы сделали это с шевелением сугроба), а в основном тайм-лайне просто включаем этот объект (active) в нужный момент и анимация начинается.
Это уже гораздо лучше, но все равно не идеально. Ведь в таком случае мы должны в нашем основном таймлайне знать, какой длины анимация этого вылезания. Чтобы включить и отключить ее в нужный момент. А что если мы опять-таки поменяем эту анимацию и заяц будет дольше смотреть по сторонам? Да и вообще, в каких-то более сложных случаях нам будет еще сложнее уместить все в один таймлайн.
Идеально было бы иметь возможность поставить основной таймлайн на паузу, начать проигрывание вложенной анимации и снять его с паузы уже по окончании этой вложенной анимации (или по какому-то событию в ней).
То есть сделать так:

1. движение влево
2. прячем пульсирующий сугроб, показываем анимацию вылезания кролика, встаем на паузу
3. прячем анимацию вылезание кролика, показываем шевелящийся сугроб, двигаемся вправо
Что нам для этого понадобится? Unity позволяет добавлять на анимацию вызов кастомных юзер event’ов. Это именно то, что нам нужно! Осталось только правильно все написать.
Первое, что нам понадобится, это написать простой компонент (в нашем случае он называется GJAnim ) и повесить его на тот же объект, на котором висит наш аниматор. Именно методы этого компонента мы сможем вызывать событиями с таймлайна.
Напишем метод для постановки на паузу. Кстати, в юнити нет такой прямой возможности. Для того, чтобы поставить на паузу анимацию, обычно применяется немного грязный хак с выставлением ее скорости в 0. Он в целом работает, правда, странности есть (об этом — в последней части статьи).
Где _animator — это переменная, в которой мы закешировали компонент » Animator «:
Если вы обратили внимание на скрин выше, над ключевым кадром, который я пометил цифрой «2» стоит небольшая вертикальная черта. Именно за ней скрывается вызов события (метода) «Pause»:

Стоит отметить, что в такие события можно даже передавать параметр. Поддерживаются string, float и объект из библиотеки (не со сцены).
Ок, на паузу мы поставили. Теперь задача — снять с паузы. Очевидно, это должна делать вложенная анимация. То есть доиграла анимация вылезающего кролика до конца, и прокинула наверх события «пошли дальше».
Этот метод ищет среди родителей компонент » GJAnim » и снимает его с паузы. Соответственно, ставим это событие на окончание анимации нашего кролика:

Profit!
Собственно, все. Мы написали простой компонент, который позволяет управлять вложенными/родительскими анимациями и обладает достаточной гибкостью. Возможно, понадобится еще метод типа ResumeByName(string) , который бы снимал с паузы конкретную анимацию, а не первую родительскую.
Кроме того, все делается в пределах юнитевского UI и достаточно прозрачно для любого аниматора. Наш художник через час попадания ему в руки этого инструмента, уже во всю анимировал.
О багах Unity и сумасшествии.
Однако, не все так гладко. В какой-то момент, создав анимацию, мы увидели, что она ведет себя неправильно.
У нас была родительская (главная) анимация, которая показывала один объект (скрывала все остальные), вставала на паузу, в это время в этом объекте начинала проигрываться своя (вложенная) анимация, которая снимала родителя с паузы по окончании. Далее — показывался следующий объект и т.п.
Так вот, мы заметили, что кадры иногда проскакивают.
Долго-долго дебажили, много писали в лог… и вот что выяснили:
По видимому, в юнити есть какой-то стэк кадров/событий анимаций. И когда компьютер (редактор unity) подтормаживает, он может положить в этот стек сразу два кадра, чтобы в следующую итерацию выполнить их оба.
Это влечет за собой чуть ли не полностью неисправимый фейл. Мы ловили ситуацию, когда аниматор выполнял все действия с кадром и вставал на паузу (это ок), а потом в этот же кадр выполнял еще и следующий кадр. То есть за один кадр рассчитывал сразу два кадра анимации. И то, что в 1-м кадре было событие, ставящее скорость анимации в 0, не мешало ему рассчитать еще и следующий кадр, который, по видимому, уже лежал в стеке.
И если в анимации с кроликом этого бы никто не заметил (кролик бы вылез на пиксель не на том месте), то когда вы каждый кадр что-то прячете и показываете, тут может быть фейл.
На данный момент проблема выглядит неисправимой. Как мы справились? Поставили FPS таких анимаций в 20. Видимо, на таком FPS’е случая, когда юнити хочет просчитать два кадра за одну итерацию — не случается.
Но все равно, ситуация не очень. Получается, что при каких-то фризах на компьютере (или на очень тормозных), все равно игрок сможет словить сбой анимаций.
Покадровая спрайтовая 2д анимация в Unity

В Unity, как и во многих других движках существует несколько видов анимации. Но в данной статье речь пойдёт о покадровой спрайтовой анимациии. Это именно та анимация, которая присутствовала в играх на наших игровых приставках, и к которой все привыкли. Суть спрайтовых анимаций заключается в быстрой смене готовых кадров, которые создают эффект анимации.
В данной статье мы разберём анимацию на примере трёх самых популярных состояний в 2д платформере:
- Состояние покоя
- Бег, или ходьба
- Прыжок
Подготовка кадров
Первым делом нам необходимо загрузить в окно Project спрайты для наших анимаций. На изображении ниже, я загрузил все необходимые кадры анимаций в три спрайта для каждого состояния(покоя, прыжок, бег). Вы можете все кадры использовать отдельными спрайтами, а можете сгруппировать как у меня. Это впринципе не важно.

Создание Анимации (Animation)
Теперь нам необходимо каждое из состояний анимировать. Для этого открываем окно Animation, с помощью вкладки Window — Animation — Animation. Откроется данное окно.

Благодаря этому окну, мы и будем превращать наши кадры в анимацию. Для этого выбираем игровой объект, который анимируем, в нашем случае это персонаж с именем Player. А далее нажимаем кнопку Create, которая изображена на рисунке выше. Далее откроется окно, в котором необходимо указать название для нашей первой анимации покоя. Назовём её idle. Готово, наша анимация создана, но пока она ещё пустая, и не имеет никаких кадров.
Важно №1. После создания ПЕРВОЙ анимации, автоматически создаётся и контроллер анимаций(Animator), с таким же названием, как и у объекта, которому мы и создаём анимацию. В моём случае название аниматора будет Player. Контроллер анимаций хранит ВСЕ состояния анимаций данного объекта(покой, бег, прыжок), и благодаря ему происходит смена этих состояний анимаций с одной на другую. На рисунке у нас создана пока ещё пустая анимация покоя idle, и контроллер анимаций Player.

Важно №2. Так же, после создания первой анимации, в Inspector-е данного объекта создаётся и компонент Animator, который несёт в себе ссылку на наш контроллер анимаций. Благодаря этому компоненту мы и будем в дальнейшем через скрипт C# менять состояния анимаций с одной в другую.

Перейдём к окну Animation. Перенесём наши спрайты из окна Project, в пустое пространство окна Animation. После нажатия клавиши "пробел", Вы можете обнаружить, что ваш персонаж на игровой сцене начинает анимироваться.

Скорее всего смена кадров у Вас происходит очень быстро, и чтобы исправить эту проблему, необходимо ЛИБО вручную увеличить расстояние между Вашими кадрами, ЛИБО снизить частоту кадров в секунду. Обычно используют второй вариант.
Для этого открываем меню в правом верхнем углу(три точки), и ставим галочку на Show Sample Rate. А дальше снижаем значение кадров в поле Samples, например, до 12.

Отлично. Анимация состояния покоя idle готова! Теперь создадим вторую анимацию, бег. Для этого в окне Animation жмём треугольничек, напротив названия Вашей анимации, и в выпадающем списке жмём Create New Clip. После чего прописываем название Вашей анимации бега, например run, и сохраняем.

После чего была создана новая и пустая анимация бега. Теперь всё так же как и в предыдущем примере, перетаскиваем кадры бега в окно Animation, уменьшаем количество кадров, и всё. Таким же образом создаём анимацию прыжка, с названием, например, jump.
После всех проделанных манипуляций, у нас должно получится 3 анимации(idle, run, jump) и один контроллер(Animator) Player.

Контроллер Анимаций (Animator)
Теперь поработаем с контроллером анимаций. Открываем наш контроллер либо через вкладку Window — Animation — Animator, либо кликнув 2 раза по нашему аниматору Player в окне Project. Откроется окно Animator, которое будет выглядеть примерно так.

Для начала обратим своё внимание на зелёный блок Entry, это начальная точка аниматора. А оранжевая стрелочка, которая исходит от блока Entry указывает на стартовую анимацию, которая будет воспроизведена сразу после запуска сцены. С помощью таких стрелочек, нам нужно указать все возможные переходы от одних анимаций к другим.
Например, от состояния покоя idle анимация может быть переключена на анимацию бега run. И это нам нужно указать через стрелочки. Для этого правой кнопкой мыши нажмём на анимацию idle. Далее в выпадающем списке жмём Make Transition, и далее указываем к какому блоку будет вести стрелочка. Укажем на блок run. Ура, стрелочка прехода создана. Создаём такие же стрелочки и между другими анимациями. У Вас должно получится так:

Так же обратите внимание на блок Any Stay, что означает Любое Состояние. Например, чтобы не создавать много стрелочек от множества анимаций к анимации jump, можно сделать всего одну стрелочку от Any State. Это будет тоже самое.
Теперь настроим наши переходы. Для этого жмём на любую БЕЛУЮ стрелочку, и в окне Inspector проводим следующие настройки:
- В поле Has Exit Time убираем галочку, чтобы анимация прерывалась сразу же, как произойдёт смена анимаций на другую.
- В поле Transition Duration указываем значение 0, чтобы переход между анимациями был не плавный, а мгновенный.
Такие же настройки нужно проделать со ВСЕМИ БЕЛЫМИ стрелочками.
Готово! Теперь необходимо создать условия, при которых будет осуществляться переход из одной анимации к другой. Для этого создадим две переменные. Одна переменная будет хранить информацию о том, бежит ли наш персонаж — если да, то будем воспроизводить анимацию бега. А вторая переменная будет хранить информацию о том, находится ли наш персонаж в прыжке — если да, то воспроизводим анимацию прыжка.
Создадим эти две переменные с названиями moveX и Jumping с типами Float и Bool соответственно. Для этого в этом же окне выбираем Parametrs, жмём на плюсик, и выбираем тип. Далее указываем название этих переменных.

Переменные созданы, теперь необходимо создать 5 условий перехода, для каждой белой стрелочки. Приведу пример, как создать условие перехода с idle на run. Для этого жмём на белую стрелочку перехода между этими анимациями, и в окне Inspector находим отдел Conditions, в котором указываем, что переход осуществляется тогда, когда переменная moveX имеет значение больше чем 0.1 — то-есть находится в движении по оси X:

По такой же примеру необходимо создать ещё 4 условия для остальных белых стрелочек перехода.
- От run к idle: переменная moveX имеет значение меньше чем 0.1
- От Any State к jump: переменная jumping имеет значение true.
- От jump к idle: переменная jumping имеет значение false.
- От jump к run: переменная jumping имеет значение false.
Запуск анимаций через скрипт
Мы почти завершили. Отсалось совсем немного. Теперь нам необходимо в эти переменные занести данные из нашего скрипта C#, во время передвижения персонажа и прыжка.
Для этого откройте свой C# скрипт, в котором прописана ваша функция передвижения персонажа, и для начала объявите переменную anim, в котором будет хранится ссылка на наш контроллер.
Далее в методе Start() или Awake() присвоим ссылку к нашей переменной:
Отлично, теперь с помощью метода SetFloat() установим нашей переменной moveX значения полученное от нашего передвижения Mathf.Abs(Input.GetAxisRaw("Horizontal")) по модулю:
Теперь как только персонаж начнёт своё движение, будет воспроизведена анимация бега. А если персонаж остановится, то анимация бега перейдёт в состояние покоя.
Теперь работа с прыжком:
В вашем скрипте должна быть переменная, которая отвечает за то, находится ли персонаж на земле или нет. У меня эта переменная называется isGround. Необходимо проверять, если персонаж на земле, то в переменную Jumping заносим false, и анимация прыжка не воспроизводится. А если персонаж находится не на земле, то нужно в переменную Jumping записать true — которая и воспроизведёт анимацию прыжка:
На это всё! Поздравляем, анимация готова.
Важно: В некоторых случаях, в зависимости от анимации прыжка, нам необходимо отменить циклическое воспроизведение анимации прыжка. Поэтому нажмите на стрелочку, исходящую от Any State ведущая к jump, и в окне Inspector в поле Can Transition To поставьте галочку.

Теперь уже точно всё! Надеюсь мне получилось объяснить принцип создания спрайтовой покадровой анимации. Так же напомню, что существует так же и костная анимация, которая так же довольно часто используется. Поэтому, если Вам интересна данная тема, то можете посетить наш гайд по созданию костной 2д анимации.
Если возникли вопросы, задавайте их в комментариях. И не забудьте поставить лайк за столь большой труд 🙂
Animating Sprites in Unity
Animations have always been an integral part of game development. They bring a sense of liveliness or relatability to games. There are various ways to animate game objects in unity. Let’s look at one such method which deals with animating with the help of sprites.
What are Sprites?
Think of Sprites as a set of 2D images that when overlaid together form an animation in a scene.
How to Use Sprites to animate in Unity?
In order to animate in Unity we are first required to open an Animation window which can then be used to create our required animation.
Select the game object you wish to animate. Then select the Window option from the tool bar. This should bring a drop down list which will contain an Animation option which further contains an Animation option, selecting them will bring a pop-up Animation window which you can then dock at your desired position.
With that done, lets create an animation,
We can now drag all our sprites related to our Animation into our Dopsheet.
Here, we observe that once the Sprites have been added into the dope sheet, we are able to extend or shorten the time frame which impacts the duration of the animation.
Now lets add a few more animations to the player,
Similarly, create an animation for an idle state and add its respective sprites. With that done, we can now move onto using the animation controller.
The Project panel contains our Animator.
With this lets use our Idle, TurnLeft and TurnRight animations to animate our character.
Here, each animation can be considered as an individual state, where given certain conditions we can transition between those states. Think of it as heating liquid at boiling point transitions it into a gaseous state, similarly freezing the liquid solidifies it. The same way we can transition from our Idle state to TurnLeft if we are pressing the left key(a) or transition to TurnRight state if we are holding down on the right key (d)on the keyboard. This is done in three steps,
Step-1: Make transitions from the idle state to the respective states and vice versa.
Step-2 : Create a variable through which we can decide when to transition between states.
Step-3 : Set conditions using the Variable created.
So basically,
Idle State → TrunLeft = when Direction is less than 0
Idle State → TrunRight = when Direction is greater than 0
TurnLeft → Idle State = when Direction is less than 1 and greater than -1
TurnRight → Idle State = when Direction is less than 1 and greater than -1
TurnLeft → TurnRight = when Direction is greater than -1 and greater than 0
TurnRight → TrunLeft = when Direction is less than 1 and less than 0
Step-4 : We now need a way to influence this Animator Direction variable through script.
_animator variable will store our Animation component.
With this we can now use _animator to influence the Direction, which will contain the direction we’re moving(since we’re using GetAxisRaw to fetch user input which returns -1, 0, 1 depending on the direction we’re moving).
By default all our animations are set to loop over again and again, so lets toggle it OFF as we want the animation to run once only when called.
Lastly, if you want your animations to play for a certain amount of time after transition, you can toggle Has Exit Time ON. In this case I don’t want any exit time I want the transition to be instantaneous.
This gives us the following result,
We can also add an animation directly to a game object as shown below and it’ll continue to loop, result is as follows,
Creating a 2D game
Before you create a 2D game, you need to decide on a game perspective and an art style.
To create a 2D game, set up your Unity project and then familiarize yourself with the relevant concepts in the following order:
Sprites A 2D graphic objects. If you are used to working in 3D, Sprites are essentially just standard textures but there are special techniques for combining and managing sprite textures for efficiency and convenience during development. More info
See in Glossary
Fundamentals
GameObjects The fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to it. More info
See in Glossary are fundamental objects in Unity that represent characters, props, scenery, and more. Every object in your game is a GameObject.
GameObjects represent the items in your game; the space in which you place them to build your level is called a scene A Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary . Scenes in Unity are always 3D; when you make a 2D game in Unity, you typically choose to ignore the third dimension (the z-axis) but you can also use it in special cases, for example when making 2.5D games.
The behavior of GameObjects is defined by blocks of functionality called components. The following components are fundamental for 2D games:
Transform: the Transform component A Transform component determines the Position, Rotation, and Scale of each object in the scene. Every GameObject has a Transform. More info
See in Glossary determines the Position, Rotation, and Scale of each GameObject in the scene. Every GameObject has a Transform component.
Sprite Renderer A component that lets you display images as Sprites for use in both 2D and 3D scenes. More info
See in Glossary : the Sprite Renderer component renders the Sprite and controls how it looks in a scene.
Cameras A component which creates an image of a particular viewpoint in your scene. The output is either drawn to the screen or captured as a texture. More info
See in Glossary : devices that capture and display the world to the player. Marking a Camera as Orthographic removes all perspective from the Camera’s view. This is mostly useful for making isometric or 2D games.
Collider 2D: this component defines the shape of a 2D GameObject for the purposes of physical collisions A collision occurs when the physics engine detects that the colliders of two GameObjects make contact or overlap, when at least one has a Rigidbody component and is in motion. More info
See in Glossary . See 2D Physics.
Components are UI (User Interface) Allows a user to interact with your application. Unity currently supports three UI systems. More info
See in Glossary representations of C# classes; you can use scripts to change and interact with components, or create new ones. See the Scripting section for more details.
Scripting
All 2D games need scripts A piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary . Scripts respond to input from the player and arrange for events in the gameplay to happen when they should.
For details on how to use scripts in Unity see Scripting Overview. Also see the Unity Learn Beginner Scripting course.
Scripts are attached to GameObjects, and any script you create inherits from the MonoBehaviour class.
Sprites
Sprites are 2D graphic objects. You use Sprites for all types of 2D games. For example, you can import an image of your main character as a Sprite.
A character Sprite
You can also use a collection of Sprites to build a character. This allows you greater control over the movement and animation of your characters.
Multiple Sprites that make up the parts of a character, displayed in the Sprite Editor
Importing and setting up Sprites
Import your Sprites with Unity’s recommended settings; see Importing and Setting Up Sprites.
Rendering Sprites
Use the Sprite Renderer component to render your Sprites. For example, you can use the Sprite Renderer to change the color and opacity of a Sprite.
Adjusting the color of a Sprite with the Sprite Renderer
See the Introduction to the Sprite Renderer Learn tutorial. Sorting SpritesBy organizing Sprites in layers, you can create an illusion of depth. You can sort Sprites according to many strategies. See Sorting Sprites for full details. For example, you might sort Sprites along the y-axis, so that Sprites that are higher up are sorted behind Sprites that are lower, to make the Sprites that are higher appear further away than the Sprites that are lower.
Sprites sorted along the y-axis
To set the overlay order of Sprites, use Sorting Layers.
To group GameObjects with Sprite Renderers, and control the order in which they render their Sprites, use Sorting Groups.
Sprite Atlas
You can use a Sprite Atlas A texture that is composed of several smaller textures. Also referred to as a texture atlas, image sprite, sprite sheet or packed texture. More info
See in Glossary to consolidate several Textures into a single combined Texture. This optimizes your game and saves memory. For example, you can add all your Sprites associated with a particular character or purpose to a Sprite Atlas.
A Sprite Atlas
Building in-game environments
Environment design refers to the process of building your game’s levels and environments. You can combine the environment design tools in this section in whichever way makes the most sense for your game; for example, you can make a top-down game using only 9-slice, or you can make a side on platformer with Tilemap and SpriteShape.
9-slicing
9-slicing is a 2D technique that allows you to reuse an image at various sizes without needing to prepare multiple assets. Unity can dynamically stretch and tile designated parts of a Sprite to allow one Sprite to serve as the border or background for UI elements of many sizes. See 9-slicing sprites.
For example, you could use 9-slicing to stretch a Sprite to shape when you build a 2D level.
A 9-sliced Sprite, split into nine sections
Tilemap
The Tilemap A GameObject that allows you to quickly create 2D levels using tiles and a grid overlay. More info
See in Glossary component is a system that stores and handles Tile assets for creating 2D levels. Use the 2D Tilemap Editor package (installed by default) to use Tilemaps.
For example, you can use Tilemaps to paint levels using Tiles and brush tools and define rules for how Tiles behave.
The Tile Palette window, used to edit Tilemaps
2D Tilemap Extras
To add some extra Tilemap assets to your Project, install the 2D Tilemap Extras package. This package contains reusable 2D and Tilemap Editor scripts that you can use for your own Projects. You can customize the behavior of the scripts to create new Brushes that suit different scenarios.
Isometric Tilemaps
For games with isometric perspective, you can create Isometric Tilemaps.
SpriteShape
In a similar way to a vector drawing tool, SpriteShape provides a more flexible way to create larger Sprites, such as organic-looking landscapes and paths. See the Sprite Shape Profile.
A path created in SpriteShape
Character animation
There are three different ways you can animate 2D characters:
| 2D animation type | Used for |
|---|---|
| Frame-by-frame | Artistic reasons, if you want your game to have a classic animation art style. Frame-by-frame animation is relatively resource-intensive, both to make and to run. |
| Cutout | Smooth skeletal animation, when the characters don’t require realistic articulation. |
| Skeletal | Smooth skeletal animation where Sprites bend according to the bone structure. Use this when the characters need a more organic feel. |
Frame-by-frame
Frame-by-frame animation is based on the traditional cel animation technique of drawing each moment of an animation as individual images, which are played in fast sequence, like flipping pages on a flipbook.
To do frame-by-frame animation, follow the Frame-by-frame Animation workflow.
Frame-by-frame animation in the Sprite Editor
Cutout
In cutout animation, multiple Sprites make up the body of a character, and each piece moves to give the visual effect of the whole character moving. This animation style is similar to skeletal animation (see below), except that the Sprites don’t bend.
Cutout animation in the Sprite Editor
Skeletal
With skeletal animation, you map a Sprite or a group of Sprites onto an animation skeleton. You can create and define animation bones for characters and objects, that define how they should bend and move. This approach allows the bones to bend and deform the Sprites, for a more natural movement style. To use skeletal animation, you need to use the 2D Animation package (installed by default).
For a 2D Animation workflow, including a guide to working with the Bone Editor, see the 2D Animation documentation.
A character with bones in the Bone Editor
Graphics
This section describes your graphics options when using Universal Render Pipeline A series of operations that take the contents of a Scene, and displays them on a screen. Unity lets you choose from pre-built render pipelines, or write your own. More info
See in Glossary (URP).
Lighting
Because you’re using URP with the 2D Renderer, you can use the Light 2D component to apply optimized 2D lighting to Sprites. For details, see Introduction to Lights 2D.
These two images show the same scene; in the image on the left, 2D Lights are disabled, and in the image on the right, 2D lights are enabled. With 2D Lights, you can use the same Sprites to create different weather conditions or moods.
To set up lighting:
Prepare your Sprites for lighting. For details, see Preparing Sprites for Lighting.
Set up normal map A type of Bump Map texture that allows you to add surface detail such as bumps, grooves, and scratches to a model which catch the light as if they are represented by real geometry.
See in Glossary and mask Textures. 2D Lights can interact with normal map and mask Textures linked to Sprites to create advanced lighting effects, such as normal mapping. See Setting up normal map and mask Textures.
Create a 2D Light GameObject; see 2D Lights Properties.
Configure the 2D Renderer Data asset; see Configuring the 2D Renderer Asset.
(Optional) if you want to apply 2D Light effects to a pixel The smallest unit in a computer image. Pixel size depends on your screen resolution. Pixel lighting is calculated at every screen pixel. More info
See in Glossary art game, see 2D Pixel Perfect.
Shadows
To define the shape and properties that a Light uses to determine the shadows it casts, use the Shadow Caster 2D component. Increase the Light’s Shadow Intensity above zero.
A shadow intensity of 0.5 in the Shadow Caster 2D component
Enhanced look and feel
Particle systems and post-processing A process that improves product visuals by applying filters and effects before the image appears on screen. You can use post-processing effects to simulate physical camera and film properties, for example Bloom and Depth of Field. More info post processing, postprocessing, postprocess
See in Glossary are optional tools that you can use to add polish to your game.
Particle systems
You can use particle systems to create dynamic objects like fire, smoke or liquids, as an alternative to using a Sprite. Sprites are more suited to physical objects. See Particle systems A component that simulates fluid entities such as liquids, clouds and flames by generating and animating large numbers of small 2D images in the scene. More info
See in Glossary .
A fire effect, created with the Particle System and Shader Graph for 2D
Post-processing
You can use post-processing effects and full-screen effects to significantly improve the appearance of your game. For example, you can use these effects to simulate physical camera or film properties, or to create stylized visuals.
URP has its own post-processing implementation. See Post-processing in the Universal Render Pipeline.
The Lost Crypt demo uses the bloom and vignette post-processing effects
Physics 2D
The Physics 2D settings define limits on the accuracy of the physical simulation in your 2D game. See 2D Physics.
This video provides an overview of 2D physics features in Unity 2020.1.
To learn how to use Unity’s 2D physics engine A system that simulates aspects of physical systems so that objects can accelerate correctly and be affected by collisions, gravity and other forces. More info
See in Glossary , see the 2D Physics Learn tutorial.
The following 2D physics tools are useful for 2D games.
Rigidbody 2D
A Rigidbody A component that allows a GameObject to be affected by simulated gravity and other forces. More info
See in Glossary 2D component places a GameObject under the control of the physics engine. See Rigidbody 2D.
The Rigidbody 2D component
Collider 2D
Collider 2D components define the shape of a 2D GameObject for the purposes of physical collisions. You can also use Collider An invisible shape that is used to handle physical collisions for an object. A collider doesn’t need to be exactly the same shape as the object’s mesh — a rough approximation is often more efficient and indistinguishable in gameplay. More info
See in Glossary 2D components for input detection. For example, in mobile games you can use them to make Sprites selectable.
The Collider 2D types that you can use with Rigidbody 2D are:
Triggers
When you set a Collider 2D as a Trigger (by enabling its Is Trigger property), it no longer behaves as a physical object, and it can intersect with other Colliders without causing a collision. Instead, when a Collider enters its space, Unity calls the OnTriggerEnter function on the Trigger GameObject’s scripts.
The Circle Collider 2D component with Is Trigger selected
2D Joints
Joints attach GameObjects together. You can only attach 2D joints A physics component allowing a dynamic connection between Rigidbody components, usually allowing some degree of movement such as a hinge. More info
See in Glossary to GameObjects that have a Rigidbody 2D component attached, or to a fixed position in world space. See 2D Joints.
2D Effectors
Use Effector 2D components A functional part of a GameObject. A GameObject can contain any number of components. Unity has many built-in components, and you can create your own by writing scripts that inherit from MonoBehaviour. More info
See in Glossary with Collider 2D components to direct the forces of physics in your scene when GameObject Colliders come into contact with each other. See 2D Effectors.
Audio
You can add background music and sound effects to your game in Unity; see Audio Overview. Use third-party software to create your audio and import it into Unity with the recommended settings.
User interface
If you want to add a menu or help to your game, you need to set up a user interface. To set up a user interface, use Unity UI.
Profiling, optimizing and testing a build
Profiling
Profiling allows you to see how resource-intensive the different parts of your game are. You should always profile your game on its target release platform; see Profiling your application.
Optimizing
After profiling, you can use the results to make performance improvements and optimizations. See Understanding optimization in Unity.
Testing
Test your game and your code with the Unity Test Framework; see Unity Test Framework.
The Test Runner window
Publishing
When you’ve finished your game, you’re ready to publish it. See Publishing Builds.
The Build Settings window