Unity создание персонажа 2d. Вешаем контроллы. Создание скелета. Подготовка

Unity создание персонажа 2d. Вешаем контроллы. Создание скелета. Подготовка

23.03.2019


Часть 2: бегущий персонаж

Каждому здравствуй. Продолжаем дело, начатое в первой части. Теперь у нас есть платформа и стоящий на ней персонаж с анимацией покоя. Настало время обучить нашего персонажа бегать вправо-налево по платформе.

Загрузим сцену из первой части. Напомню, что в прошлый раз мы импортировали несколько спрайтов в папкуAssets - Sprites . На каждый случай, внизу поста еще раз приведу ссылку на спрайты. Среди них должен быть спрайт под наименованием Run . Мы будем применять его для создания анимации бега. Для этого нам нужно проделать те же действия по перевоплощению одиночного спрайта в коллекцию, как и при создании анимации покоя. Лаконично напомню: выделяем спрайт, в окне Inspector устанавливаем качество Sprite Mode какMultiple , нажимаем ниже Sprite Editor , нарезаем изображение в режиме Grid либо Automatic .

Сейчас в окне Hierarchy выбираем Character и переходим в окно Animation . Нажимаем на поле с анимацией Idle и выбираем Create New Clip , Дабы сделать анимацию бега. Сбережем файл анимации в папке Assets -Animations под именем Run .

Новая сделанная анимация Run стала нынешней в окне Animation . Разворачиваем спрайт Run в окне Project , выделяем все фалы Run_0… Run_9 и перетаскиваем в окно Animation . Установим пока значение Sample равное 24.

Все это мы теснее делали в первой части, а сейчас будет что-то новое. Перейдем в окно Animator . Теперь там отображены три анимации: Any State , Idle и Run . Нам предстоит задать данные перехода из анимации Idle в анимацию Run , то есть из состояния покоя в состояние бега. В нижнем левом углу есть поле Parameters . Нажимаем на плюсик, выбираем Float и называем новейший параметр как Speed . Тем самым мы сотворили параметр типа число с плавающей запятой, обозначающий скорость перемещения персонажа. Именно в зависимости от значения этого параметра будет протекать переключение из анимации покоя в анимацию бега. Сейчас нажимаем правой кнопкой мыши на анимацию Idle , выбираем Make Transition и нажимаем левой кнопкой мыши на анимацию Run . Между анимациями появится линия со стрелкой. Передвиньте мышкой прямоугольники анимации, если нехорошо видно. Кликнем по линии со стрелкой. В окне Inspector отобразятся свойства перехода между анимациями. Обратим внимание на низ окна, в раздел Conditions . Кликнем на параметр Exit Time и поменяем его на Speed . Второе поле Greater оставим без изменений, а в третьем введем значение 0.01 . Мы сделали условие перехода из анимации покоя в анимацию бега - оно происходит, когда значение параметра скорости становится немногим огромнее нуля.

Сейчас необходимо сделать обратный переход - из Run в Idle . Делаем все с точностью напротив: Make Transition от Run к Idle , выделяем переход, в Conditions устанавливаем Speed - Less - 0.01 .

Сейчас у нас есть две анимации и данные перехода между ними. Но пока ничего трудиться не будет, потому что все что мы сделали необходимо «оживить» при помощи скрипта. Давайте перейдем в окно Project и сотворим в папке Assets подпапку Scripts . Добавим в нее новейший C# Script , назовем егоCharacterControllerScript и откроем на редактирование.

Я приведу полный листинг скрипта с подробными комментариями, а ниже еще поясню, что в нем происходит.

Using UnityEngine; using System.Collections; public class CharacterControllerScript: MonoBehaviour { //переменная для установки макс. скорости персонажа public float maxSpeed = 10f; //переменная для определения направления персонажа вправо/влево private bool isFacingRight = true; //ссылка на компонент анимаций private Animator anim; ///

/// Исходная инициализация /// private void Start() { anim = GetComponent(); } /// /// Исполняем действия в способе FixedUpdate, т. к. в компоненте Animator персонажа /// выставлено значение Animate Physics = true и анимация синхронизируется с расчетами физики /// private void FixedUpdate() { //используем Input.GetAxis для оси Х. способ возвращает значение оси в пределах от -1 до 1. //при стандартных настройках плана //-1 возвращается при нажатии на клавиатуре стрелки налево (либо клавиши А), //1 возвращается при нажатии на клавиатуре стрелки вправо (либо клавиши D) float move = Input.GetAxis("Horizontal"); //в компоненте анимаций изменяем значение параметра Speed на значение оси Х. //приэтом нам необходим модуль значения anim.SetFloat("Speed", Mathf.Abs(move)); //обращаемся к компоненту персонажа RigidBody2D. задаем ему скорость по оси Х, //равную значению оси Х умноженное на значение макс. скорости rigidbody2D.velocity = new Vector2(move * maxSpeed, rigidbody2D.velocity.y); //если нажали клавишу для перемещения вправо, а персонаж направлен налево if(move > 0 && !isFacingRight) //отражаем персонажа вправо Flip(); //обратная обстановка. отражаем персонажа налево else if (move < 0 && isFacingRight) Flip(); } /// /// Способ для смены направления движения персонажа и его зеркального отражения /// private void Flip() { //меняем направление движения персонажа isFacingRight = !isFacingRight; //получаем размеры персонажа Vector3 theScale = transform.localScale; //зеркально отражаем персонажа по оси Х theScale.x *= -1; //задаем новейший размер персонажа, равный ветхому, но зеркально отраженный transform.localScale = theScale; } }

Выходит, мы завели несколько переменных: для задания максимальной скорости перемещения, для определения направления (вправо/влево) и для работы с компонентом Animator . Примерно все действия происходят в способе FixedUpdate . В нем мы получаем значение оси Х , которое меняется при нажатии на клавиатуре клавиш налево-вправо либо A-D (если не меняли соответствующие настройки плана!). После этого устанавливаем это значение параметру Speed компонента Animator . Обратите внимание, что мы берем модуль этого значения при помощи способа Mathf.Abs , так как при создании условий перехода между анимациями покоя и бега мы сопоставляем значение параметра с позитивным числом 0.01 . Нам тут не значимо, в какую сторону бежит персонаж. Значимо лишь величина значения. Дальше задаем скорость перемещения по оси Х в соответствии со значением максимальной скорости. И, наконец, проверяем, в какую сторону бежит персонаж, и в какую сторону он в данный момент повернут. Если он бежит вправо, а повернут налево - разворачиваем его вправо путем инвертирования его размера по оси Х . И напротив. Этим нехитрым методом мы избавились от необходимости делать две анимации взамен одной: для бега вправо и для бега налево.

Сберегаем скрипт. В Unity перетаскиваем его на нашего Character в окне Hierarchy . Запускаем игру, нажимаем налево-вправо либо A-D.

Капитан Коготь сейчас может бегать! Скорость анимации получилась быстроватой. Ее дозволено снизить путем уменьшения значения Sample в окне Animation для анимации Run (значение 12 будет типично). Если единовременно с игрой у вас видно окно Animator , то вы ув

В этой статье поговорим о 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. Он в целом работает, правда, странности есть (об этом - в последней части статьи).

Public void Pause() { _animator.speed = 0; } protected void Resume() { _animator.speed = 1; }

Где _animator - это переменная, в которой мы закешировали компонент " Animator ":

Animator = GetComponent();

Если вы обратили внимание на скрин выше, над ключевым кадром, который я пометил цифрой «2» стоит небольшая вертикальная черта. Именно за ней скрывается вызов события (метода) «Pause»:


Стоит отметить, что в такие события можно даже передавать параметр. Поддерживаются string, float и объект из библиотеки (не со сцены).

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

Public void ResumeParent() { Transform pr = transform; while (true) { pr = pr.parent; if (pr == null) { Debug.LogWarning("No GJAnim found in parents!"); return; } GJAnim a = pr.gameObject.GetComponent(); if (a != null) { a.Resume(); return; } } }

Этот метод ищет среди родителей компонент " GJAnim " и снимает его с паузы. Соответственно, ставим это событие на окончание анимации нашего кролика:


Profit!

Собственно, все. Мы написали простой компонент, который позволяет управлять вложенными/родительскими анимациями и обладает достаточной гибкостью. Возможно, понадобится еще метод типа ResumeByName(string) , который бы снимал с паузы конкретную анимацию, а не первую родительскую.

Кроме того, все делается в пределах юнитевского UI и достаточно прозрачно для любого аниматора. Наш художник через час попадания ему в руки этого инструмента, уже во всю анимировал.

О багах Unity и сумасшествии.

Однако, не все так гладко. В какой-то момент, создав анимацию, мы увидели, что она ведет себя неправильно.

У нас была родительская (главная) анимация, которая показывала один объект (скрывала все остальные), вставала на паузу, в это время в этом объекте начинала проигрываться своя (вложенная) анимация, которая снимала родителя с паузы по окончании. Далее - показывался следующий объект и т.п.

Так вот, мы заметили, что кадры иногда проскакивают.

Долго-долго дебажили, много писали в лог… и вот что выяснили:

По видимому, в юнити есть какой-то стэк кадров/событий анимаций. И когда компьютер (редактор unity) подтормаживает, он может положить в этот стек сразу два кадра, чтобы в следующую итерацию выполнить их оба.

Это влечет за собой чуть ли не полностью неисправимый фейл. Мы ловили ситуацию, когда аниматор выполнял все действия с кадром и вставал на паузу (это ок), а потом в этот же кадр выполнял еще и следующий кадр. То есть за один кадр рассчитывал сразу два кадра анимации. И то, что в 1-м кадре было событие, ставящее скорость анимации в 0, не мешало ему рассчитать еще и следующий кадр, который, по видимому, уже лежал в стеке.

И если в анимации с кроликом этого бы никто не заметил (кролик бы вылез на пиксель не на том месте), то когда вы каждый кадр что-то прячете и показываете, тут может быть фейл.

На данный момент проблема выглядит неисправимой. Как мы справились? Поставили FPS таких анимаций в 20. Видимо, на таком FPS"е случая, когда юнити хочет просчитать два кадра за одну итерацию - не случается.

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

Что с этим делать - не ясно.

  • Tutorial

Часть 1: заготовка персонажа и анимация покоя
Часть 2: бегущий персонаж
Часть 3: прыжки (и падения)

Всем добрый день. В относительно недавно вышедшей Unity 4.3 появились инструменты для создания 2D игр. Конечно, такие игры можно было создавать и раньше, но это делалось при помощи дополнительных ухищрений (вот пример с хабра). Теперь же появилась поддержка 2D «из коробки». Надеюсь, разработчики продолжат ее развивать, а пока я хочу рассказать о некоторых приемах работы с новыми 2D инструментами.

Для основы урока я взял официальный видеоурок с сайта Unity3d.com. В нем создается анимированный управляемый 2D персонаж. Он может стоять, бегать, прыгать. Все это сопровождается соответствующими анимациями. Урок довольно длинный (почти полтора часа) и содержит немного «воды», поэтому я решил сделать некий текстовый перевод. В этой части речь пойдет о самых основах - создадим статичную платформу для нашего персонажа, самого персонажа, и сделаем персонажу анимацию покоя. Бег и прыжки рассмотрим позже, но основу для этого создадим сейчас. Все операции я постараюсь описывать подробно, но основные знания об интерфейсе Unity у вас должны быть. На том же официальном сайте Unity есть хорошие и быстрые уроки по интерфейсу.

Итак, начнем. Создадим новый проект в Unity. Выберем папку для расположения проекта, импортировать дополнительные пакеты не будем. Обязательно укажем, что мы создаем проект, настроенный на 2D игру (Setup defaults for: 2D ).

Проект создан. В окне Project у нас должна быть одна папка - Assets . Давайте создадим в ней подпапку Sprites , где будем хранить спрайты - графические файлы, необходимые для отображения персонажей, фона, пола, бонусов и прочих игровых объектов. Нам нужен спрайт, для отображения платформы, по которой будет бегать наш персонаж. Для этого подойдет любое прямоугольное изображение. В конце поста я указал ссылку на архив со спрайтами, которые использовались в уроке. Это немного спрайтов из игры Capitan Claw. Файл спрайта платформы называется Platform.png . Скопируем его в папку Sprites . Теперь нам надо перетащить спрайт Platform на окно Scene . В нашем проекте есть камера с именем Main Camera . Она-то и будет отображать то, что мы видим в игре. Перетащим спрайт платформы так, чтобы она оказалась в нижнем углу поля зрения камеры (если кликнуть по камере, то внизу сцены появится окошко Camera Preview , по которому можно контролировать, что в данный момент видит камера). Unity автоматически создаст игровой объект с двумя компонентами - Transform и Sprite Render . Первый отвечает за положение нашей платформы, второй - за ее отрисовку. Но нам еще нужно, чтобы персонаж не падал сквозь эту платформу, поэтому добавим к объекту платформы компонент Box Collider 2D , из раздела Physics 2D . Итого, сейчас у нас должно быть что-то вроде этого:

Теперь займемся персонажем. Создадим пустой игровой объект (Game Object - Create Empty ) и перетащим его так, чтобы он висел над левой частью платформы. Переименуем этот объект как Character и добавим к нему компонент Rigidbody 2D , для придания нашему персонажу физических свойств твердого тела. В компоненте Rigidbody 2D установим флажок Fixed Angle , чтобы предотвратить случайные вращения нашего персонажа, например, от столкновения с другими твердыми телами. Затем установим в поле Interpolate значение Interpolate . Документация Unity рекомендует устанавливать это значение для персонажей, управляемых игроком, особенно, если за ним следует камера. Это связано с синхронизацией расчета физики и отрисовкой графики. Подробности в документации.

Следующим шагом нам нужно добавить компонент Sprite Render , для отрисовки персонажа. Почему мы не можем просто перенести нужный спрайт, и получить автоматически сгенерированный Sprite Render , как в случае с платформами? Потому что наш персонаж, в отличии от платформ, будет отрисовываться не одним, а несколькими спрайтами, чтобы получился анимированный персонаж. Для этого нам придется выполнить ряд действий и первое из них - достать подходящие спрайтшиты (Sprite Sheet ). Спрайтшит - это изображение, на котором содержаться кадры анимации для нашего персонажа. Думаю, ни для кого не секрет, что анимация - последовательное и быстрое отображение неанимированных кадров, каждый из которых немного отличается от предыдущего. Погуглите по запросу Sprite Sheet , и вы сразу поймете, что это такое. Нам нужны спрайтшиты для состояний покоя, бега и прыжка. В архиве со спрайтами есть файлы Idle.png , Run.png , и Jump.png . Скопируем их в папку Sprites . На данном этапе должно быть следующее:

Приступим к анимированию персонажа, а конкретно - к анимированию состояния покоя, когда персонаж просто стоит и ничего не делает. Точнее говоря, он ничего не делает с точки зрения игровой логики, но он может переминаться с ноги на ногу, моргать, делать жесты, показывающие, что ему скучно так просто стоять и так далее. Для анимации покоя нам понадобиться файл Idle из нашей папки Sprites . Выделим этот файл. В окне Inspector отображаются свойства этого файла. Свойство Texture Type задано как Sprite , и это то, что нам нужно, а вот значение свойства Sprite Mode надо изменить с Single на Multiple . Таким образом, мы указали, что файл играет роль не одиночного спрайта, а представляет собой коллекцию спрайтов. Однако, эту коллекцию еще надо инициализировать. Для этого чуть кликнем по кнопке Sprite Editor , которая находится все в том же окне Inspector чуть ниже свойства Pixels To Units . Откроется новое окно. В нем мы видим содержимое нашего спрайтшита для состояния покоя: несколько похожих друг на друга кадров. Нам нужно их нарезать на отдельные изображения. Для этого нажмем на кнопку Slice в левом верхнем углу окна. Во-первых, нам надо задать способ (Type ) нарезки изображения: Grid или Automatic . Первый способ нарежет наше изображение сеточкой с настраиваемыми размерами ячеек (Pixel Size - X… Y...). То есть, в этом режиме надо подобрать такие значения, чтобы все кадры нормально уместились в ячейках, чтобы ничего лишнего не было отрезано и т.п. Во втором режиме нарезка на кадры будет произведена автоматически. Сама нарезка произойдет после нажатия кнопки Slice . Попробуйте применить разные способы нарезки и посмотрите, что из этого получается. В случае с моим спрайтшитом нормально подходит способ Automatic . Даже если какой-то из кадров вышел немного неудачно - его можно отредактировать, кликнув по нему и изменив значения высоты/ширины/расположения и других параметров в соответствующем окне или при помощи мышки. Подтвердим нарезку нажатием на кнопку Apply в правом верхнем углу и закроем это окно.

Теперь нам надо найти наш импортированный файл Idle в окне Project . В правой части файла есть треугольник (или в левой, при самом мелком мастабе значков). Кликнув по треугольнику, мы развернем коллекцию изображений, полученных в результате нарезки. Они будут иметь имена Idle_0 , Idle_1 и т. д. Теперь в окне Hierarchy выберем наш Character , и перетащим изображение Idle_0 в поле Sprite компонента Sprite Rende r. Наш персонаж отобразиться на сцене. Если он получился маленьким - можно увеличить его размеры до необходимых. Вот так:

Давайте сразу добавим к нашему персонажу компонент Box Collider 2D , что не проваливаться сквозь платформу. При этом откорректируем размеры и местоположение коллайдера так, чтобы он не был слишком большим и располагался на уровне ног персонажа. Этого достаточно, чтобы персонаж не падал сквозь платформу. Можете запустить игру и проверить.

Вернемся к анимации покоя. Для этого добавим к нашему Character еще один компонент - Animator (раздел Miscellaneous ). Изменим некоторые его свойства - снимем флаг с Apply Root Motion и установим флаг Anymate Physics . Apply Root Motion позволяет изменять положение объекта из самой анимации (что нам сейчас не нужно), а включенный флаг Anymate Physics задает выполнение анимации в цикле расчета физики, что как раз рекомендовано для движущихся твердых тел. Теперь создадим в папке Assets файл Animator Controller . Назовем его CharacterController . В окне Hierarchy выделим нашего персонажа Character и перетащим CharacterController в поле Controller компонента Animator :

Кликнем дважды по CharacterController - откроется новое окно Animator . В нем мы будем создавать различные состояния анимации (покой, бег, прыжок) и задавать условия перехода между ними. Для создания непосредственно анимаций нам нужно окно Animation . Если оно у вас еще не отображается его можно включить из главного меню Unity (Window - Animation ). Теперь выберем нашего персонажа Character в окне Hierarchy , а в окне Animation нажмем кнопку для создания новой анимации и выберем Create New Clip . На скриншоте ниже я отметил эту кнопку красной окружностью:

В стандартном диалоге сохранения файла сперва создадим папку Animations , а в нее сохраним наш файл анимации, назвав его Idle .

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

Осталось всего пара шагов. Переходим в папку Sprites , разворачиваем спрайт Idle , выделяем первое изображение Idle_0 , зажимаем шифт и выделяем последнее изображение Idle_7 . Все выделенные изображения переносим мышью на окно Animation . Зададим значение Sample равное 10 - этот параметр означает количество кадров анимации в секунду. Как известно, для хорошей анимации необходимо, чтобы она отображалась со скоростью не менее 24 кадров в секунду, однако, в нашем случае анимация состоит из довольно маленького числа кадров и при значении 24 она будет отображаться слишком быстро.

Запустим игру! Если все сделано правильно, наш Капитан Коготь должен стоять на платформе, дышать, и вилять хвостом.

На этом пока все. В следующий раз поговорим о реализации бегущего вправо-влево персонажа и соответствующей анимации.

Всем добрый день. В относительно недавно вышедшей Unity 4.3 появились инструменты для создания 2D игр. Конечно, такие игры можно было создавать и раньше, но это делалось при помощи дополнительных ухищрений (вот с хабра). Теперь же появилась поддержка 2D «из коробки». Надеюсь, разработчики продолжат ее развивать, а пока я хочу рассказать о некоторых приемах работы с новыми 2D инструментами.

Для основы урока я взял официальный с сайта Unity3d.com. В нем создается анимированный управляемый 2D персонаж. Он может стоять, бегать, прыгать. Все это сопровождается соответствующими анимациями. Урок довольно длинный (почти полтора часа) и содержит немного «воды», поэтому я решил сделать некий текстовый перевод. В этой части речь пойдет о самых основах - создадим статичную платформу для нашего персонажа, самого персонажа, и сделаем персонажу анимацию покоя. Бег и прыжки рассмотрим позже, но основу для этого создадим сейчас. Все операции я постараюсь описывать подробно, но основные знания об интерфейсе Unity у вас должны быть. На том же официальном сайте Unity есть хорошие и быстрые уроки по интерфейсу.

Итак, начнем. Создадим новый проект в Unity. Выберем папку для расположения проекта, импортировать дополнительные пакеты не будем. Обязательно укажем, что мы создаем проект, настроенный на 2D игру (Setup defaults for: 2D ).

Проект создан. В окне Project у нас должна быть одна папка - Assets . Давайте создадим в ней подпапку Sprites , где будем хранить спрайты - графические файлы, необходимые для отображения персонажей, фона, пола, бонусов и прочих игровых объектов. Нам нужен спрайт, для отображения платформы, по которой будет бегать наш персонаж. Для этого подойдет любое прямоугольное изображение. В конце поста я указал ссылку на архив со спрайтами, которые использовались в уроке. Это немного спрайтов из игры Capitan Claw. Файл спрайта платформы называется Platform.png . Скопируем его в папку Sprites . Теперь нам надо перетащить спрайт Platform на окно Scene . В нашем проекте есть камера с именем Main Camera . Она-то и будет отображать то, что мы видим в игре. Перетащим спрайт платформы так, чтобы она оказалась в нижнем углу поля зрения камеры (если кликнуть по камере, то внизу сцены появится окошко Camera Preview , по которому можно контролировать, что в данный момент видит камера). Unity автоматически создаст игровой объект с двумя компонентами - Transform и Sprite Render . Первый отвечает за положение нашей платформы, второй - за ее отрисовку. Но нам еще нужно, чтобы персонаж не падал сквозь эту платформу, поэтому добавим к объекту платформы компонент Box Collider 2D , из раздела Physics 2D . Итого, сейчас у нас должно быть что-то вроде этого:

Теперь займемся персонажем. Создадим пустой игровой объект (Game Object - Create Empty ) и перетащим его так, чтобы он висел над левой частью платформы. Переименуем этот объект как Character и добавим к нему компонент Rigidbody 2D , для придания нашему персонажу физических свойств твердого тела. В компоненте Rigidbody 2D установим флажок Fixed Angle , чтобы предотвратить случайные вращения нашего персонажа, например, от столкновения с другими твердыми телами. Затем установим в поле Interpolate значение Interpolate . Документация Unity рекомендует устанавливать это значение для персонажей, управляемых игроком, особенно, если за ним следует камера. Это связано с синхронизацией расчета физики и отрисовкой графики. Подробности в документации.

Следующим шагом нам нужно добавить компонент Sprite Render , для отрисовки персонажа. Почему мы не можем просто перенести нужный спрайт, и получить автоматически сгенерированный Sprite Render , как в случае с платформами? Потому что наш персонаж, в отличии от платформ, будет отрисовываться не одним, а несколькими спрайтами, чтобы получился анимированный персонаж. Для этого нам придется выполнить ряд действий и первое из них - достать подходящие спрайтшиты (Sprite Sheet ). Спрайтшит - это изображение, на котором содержаться кадры анимации для нашего персонажа. Думаю, ни для кого не секрет, что анимация - последовательное и быстрое отображение неанимированных кадров, каждый из которых немного отличается от предыдущего. Погуглите по запросу Sprite Sheet , и вы сразу поймете, что это такое. Нам нужны спрайтшиты для состояний покоя, бега и прыжка. В архиве со спрайтами есть файлы Idle.png , Run.png , и Jump.png . Скопируем их в папку Sprites . На данном этапе должно быть следующее:

Приступим к анимированию персонажа, а конкретно - к анимированию состояния покоя, когда персонаж просто стоит и ничего не делает. Точнее говоря, он ничего не делает с точки зрения игровой логики, но он может переминаться с ноги на ногу, моргать, делать жесты, показывающие, что ему скучно так просто стоять и так далее. Для анимации покоя нам понадобиться файл Idle из нашей папки Sprites . Выделим этот файл. В окне Inspector отображаются свойства этого файла. Свойство Texture Type задано как Sprite , и это то, что нам нужно, а вот значение свойства Sprite Mode надо изменить с Single на Multiple . Таким образом, мы указали, что файл играет роль не одиночного спрайта, а представляет собой коллекцию спрайтов. Однако, эту коллекцию еще надо инициализировать. Для этого чуть кликнем по кнопке Sprite Editor , которая находится все в том же окне Inspector чуть ниже свойства Pixels To Units . Откроется новое окно. В нем мы видим содержимое нашего спрайтшита для состояния покоя: несколько похожих друг на друга кадров. Нам нужно их нарезать на отдельные изображения. Для этого нажмем на кнопку Slice в левом верхнем углу окна. Во-первых, нам надо задать способ (Type ) нарезки изображения: Grid или Automatic . Первый способ нарежет наше изображение сеточкой с настраиваемыми размерами ячеек (Pixel Size - X… Y...). То есть, в этом режиме надо подобрать такие значения, чтобы все кадры нормально уместились в ячейках, чтобы ничего лишнего не было отрезано и т.п. Во втором режиме нарезка на кадры будет произведена автоматически. Сама нарезка произойдет после нажатия кнопки Slice . Попробуйте применить разные способы нарезки и посмотрите, что из этого получается. В случае с моим спрайтшитом нормально подходит способ Automatic . Даже если какой-то из кадров вышел немного неудачно - его можно отредактировать, кликнув по нему и изменив значения высоты/ширины/расположения и других параметров в соответствующем окне или при помощи мышки. Подтвердим нарезку нажатием на кнопку Apply в правом верхнем углу и закроем это окно.

Теперь нам надо найти наш импортированный файл Idle в окне Project . В правой части файла есть треугольник (или в левой, при самом мелком мастабе значков). Кликнув по треугольнику, мы развернем коллекцию изображений, полученных в результате нарезки. Они будут иметь имена Idle_0 , Idle_1 и т. д. Теперь в окне Hierarchy выберем наш Character , и перетащим изображение Idle_0 в поле Sprite компонента Sprite Rende r. Наш персонаж отобразиться на сцене. Если он получился маленьким - можно увеличить его размеры до необходимых. Вот так:

Давайте сразу добавим к нашему персонажу компонент Box Collider 2D , что не проваливаться сквозь платформу. При этом откорректируем размеры и местоположение коллайдера так, чтобы он не был слишком большим и располагался на уровне ног персонажа. Этого достаточно, чтобы персонаж не падал сквозь платформу. Можете запустить игру и проверить.

Вернемся к анимации покоя. Для этого добавим к нашему Character еще один компонент - Animator (раздел Miscellaneous ). Изменим некоторые его свойства - снимем флаг с Apply Root Motion и установим флаг Anymate Physics . Apply Root Motion позволяет изменять положение объекта из самой анимации (что нам сейчас не нужно), а включенный флаг Anymate Physics задает выполнение анимации в цикле расчета физики, что как раз рекомендовано для движущихся твердых тел. Теперь создадим в папке Assets файл Animator Controller . Назовем его CharacterController . В окне Hierarchy выделим нашего персонажа Character и перетащим CharacterController в поле Controller компонента Animator :

Кликнем дважды по CharacterController - откроется новое окно Animator . В нем мы будем создавать различные состояния анимации (покой, бег, прыжок) и задавать условия перехода между ними. Для создания непосредственно анимаций нам нужно окно Animation . Если оно у вас еще не отображается его можно включить из главного меню Unity (Window - Animation ). Теперь выберем нашего персонажа Character в окне Hierarchy , а в окне Animation нажмем кнопку для создания новой анимации и выберем Create New Clip . На скриншоте ниже я отметил эту кнопку красной окружностью:

В стандартном диалоге сохранения файла сперва создадим папку Animations , а в нее сохраним наш файл анимации, назвав его Idle .

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

Осталось всего пара шагов. Переходим в папку Sprites , разворачиваем спрайт Idle , выделяем первое изображение Idle_0 , зажимаем шифт и выделяем последнее изображение Idle_7 . Все выделенные изображения переносим мышью на окно Animation . Зададим значение Sample равное 10 - этот параметр означает количество кадров анимации в секунду. Как известно, для хорошей анимации необходимо, чтобы она отображалась со скоростью не менее 24 кадров в секунду, однако, в нашем случае анимация состоит из довольно маленького числа кадров и при значении 24 она будет отображаться слишком быстро.

Запустим игру! Если все сделано правильно, наш Капитан Коготь должен стоять на платформе, дышать, и вилять хвостом.

На этом пока все. В следующий раз поговорим о реализации бегущего вправо-влево персонажа и соответствующей анимации.

  • Unity
    • Tutorial

    Часть 1: заготовка персонажа и анимация покоя

    Всем добрый день. В относительно недавно вышедшей Unity 4.3 появились инструменты для создания 2D игр. Конечно, такие игры можно было создавать и раньше, но это делалось при помощи дополнительных ухищрений (вот с хабра). Теперь же появилась поддержка 2D «из коробки». Надеюсь, разработчики продолжат ее развивать, а пока я хочу рассказать о некоторых приемах работы с новыми 2D инструментами.

    Для основы урока я взял официальный видеоурок с сайта Unity3d.com. В нем создается анимированный управляемый 2D персонаж. Он может стоять, бегать, прыгать. Все это сопровождается соответствующими анимациями. Урок довольно длинный (почти полтора часа) и содержит немного «воды», поэтому я решил сделать некий текстовый перевод. В этой части речь пойдет о самых основах - создадим статичную платформу для нашего персонажа, самого персонажа, и сделаем персонажу анимацию покоя. Бег и прыжки рассмотрим позже, но основу для этого создадим сейчас. Все операции я постараюсь описывать подробно, но основные знания об интерфейсе Unity у вас должны быть. На том же официальном сайте Unity есть хорошие и быстрые уроки по интерфейсу.

    Итак, начнем. Создадим новый проект в Unity. Выберем папку для расположения проекта, импортировать дополнительные пакеты не будем. Обязательно укажем, что мы создаем проект, настроенный на 2D игру (Setup defaults for: 2D ).

    Проект создан. В окне Project у нас должна быть одна папка - Assets . Давайте создадим в ней подпапку Sprites , где будем хранить спрайты - графические файлы, необходимые для отображения персонажей, фона, пола, бонусов и прочих игровых объектов. Нам нужен спрайт, для отображения платформы, по которой будет бегать наш персонаж. Для этого подойдет любое прямоугольное изображение. В конце поста я указал ссылку на архив со спрайтами, которые использовались в уроке. Это немного спрайтов из игры Capitan Claw. Файл спрайта платформы называется Platform.png . Скопируем его в папку Sprites . Теперь нам надо перетащить спрайт Platform на окно Scene . В нашем проекте есть камера с именем Main Camera . Она-то и будет отображать то, что мы видим в игре. Перетащим спрайт платформы так, чтобы она оказалась в нижнем углу поля зрения камеры (если кликнуть по камере, то внизу сцены появится окошко Camera Preview , по которому можно контролировать, что в данный момент видит камера). Unity автоматически создаст игровой объект с двумя компонентами - Transform и Sprite Render . Первый отвечает за положение нашей платформы, второй - за ее отрисовку. Но нам еще нужно, чтобы персонаж не падал сквозь эту платформу, поэтому добавим к объекту платформы компонент Box Collider 2D , из раздела Physics 2D . Итого, сейчас у нас должно быть что-то вроде этого:

    Теперь займемся персонажем. Создадим пустой игровой объект (Game Object - Create Empty ) и перетащим его так, чтобы он висел над левой частью платформы. Переименуем этот объект как Character и добавим к нему компонент Rigidbody 2D , для придания нашему персонажу физических свойств твердого тела. В компоненте Rigidbody 2D установим флажок Fixed Angle , чтобы предотвратить случайные вращения нашего персонажа, например, от столкновения с другими твердыми телами. Затем установим в поле Interpolate значение Interpolate . Документация Unity рекомендует устанавливать это значение для персонажей, управляемых игроком, особенно, если за ним следует камера. Это связано с синхронизацией расчета физики и отрисовкой графики. Подробности в документации.

    Следующим шагом нам нужно добавить компонент Sprite Render , для отрисовки персонажа. Почему мы не можем просто перенести нужный спрайт, и получить автоматически сгенерированный Sprite Render , как в случае с платформами? Потому что наш персонаж, в отличии от платформ, будет отрисовываться не одним, а несколькими спрайтами, чтобы получился анимированный персонаж. Для этого нам придется выполнить ряд действий и первое из них - достать подходящие спрайтшиты (Sprite Sheet ). Спрайтшит - это изображение, на котором содержаться кадры анимации для нашего персонажа. Думаю, ни для кого не секрет, что анимация - последовательное и быстрое отображение неанимированных кадров, каждый из которых немного отличается от предыдущего. Погуглите по запросу Sprite Sheet , и вы сразу поймете, что это такое. Нам нужны спрайтшиты для состояний покоя, бега и прыжка. В архиве со спрайтами есть файлы Idle.png , Run.png , и Jump.png . Скопируем их в папку Sprites . На данном этапе должно быть следующее:

    Приступим к анимированию персонажа, а конкретно - к анимированию состояния покоя, когда персонаж просто стоит и ничего не делает. Точнее говоря, он ничего не делает с точки зрения игровой логики, но он может переминаться с ноги на ногу, моргать, делать жесты, показывающие, что ему скучно так просто стоять и так далее. Для анимации покоя нам понадобиться файл Idle из нашей папки Sprites . Выделим этот файл. В окне Inspector отображаются свойства этого файла. Свойство Texture Type задано как Sprite , и это то, что нам нужно, а вот значение свойства Sprite Mode надо изменить с Single на Multiple . Таким образом, мы указали, что файл играет роль не одиночного спрайта, а представляет собой коллекцию спрайтов. Однако, эту коллекцию еще надо инициализировать. Для этого чуть кликнем по кнопке Sprite Editor , которая находится все в том же окне Inspector чуть ниже свойства Pixels To Units . Откроется новое окно. В нем мы видим содержимое нашего спрайтшита для состояния покоя: несколько похожих друг на друга кадров. Нам нужно их нарезать на отдельные изображения. Для этого нажмем на кнопку Slice в левом верхнем углу окна. Во-первых, нам надо задать способ (Type ) нарезки изображения: Grid или Automatic . Первый способ нарежет наше изображение сеточкой с настраиваемыми размерами ячеек (Pixel Size - X… Y...). То есть, в этом режиме надо подобрать такие значения, чтобы все кадры нормально уместились в ячейках, чтобы ничего лишнего не было отрезано и т.п. Во втором режиме нарезка на кадры будет произведена автоматически. Сама нарезка произойдет после нажатия кнопки Slice . Попробуйте применить разные способы нарезки и посмотрите, что из этого получается. В случае с моим спрайтшитом нормально подходит способ Automatic . Даже если какой-то из кадров вышел немного неудачно - его можно отредактировать, кликнув по нему и изменив значения высоты/ширины/расположения и других параметров в соответствующем окне или при помощи мышки. Подтвердим нарезку нажатием на кнопку Apply в правом верхнем углу и закроем это окно.

    Теперь нам надо найти наш импортированный файл Idle в окне Project . В правой части файла есть треугольник (или в левой, при самом мелком мастабе значков). Кликнув по треугольнику, мы развернем коллекцию изображений, полученных в результате нарезки. Они будут иметь имена Idle_0 , Idle_1 и т. д. Теперь в окне Hierarchy выберем наш Character , и перетащим изображение Idle_0 в поле Sprite компонента Sprite Rende r. Наш персонаж отобразиться на сцене. Если он получился маленьким - можно увеличить его размеры до необходимых. Вот так:

    Давайте сразу добавим к нашему персонажу компонент Box Collider 2D , что не проваливаться сквозь платформу. При этом откорректируем размеры и местоположение коллайдера так, чтобы он не был слишком большим и располагался на уровне ног персонажа. Этого достаточно, чтобы персонаж не падал сквозь платформу. Можете запустить игру и проверить.

    Вернемся к анимации покоя. Для этого добавим к нашему Character еще один компонент - Animator (раздел Miscellaneous ). Изменим некоторые его свойства - снимем флаг с Apply Root Motion и установим флаг Anymate Physics . Apply Root Motion позволяет изменять положение объекта из самой анимации (что нам сейчас не нужно), а включенный флаг Anymate Physics задает выполнение анимации в цикле расчета физики, что как раз рекомендовано для движущихся твердых тел. Теперь создадим в папке Assets файл Animator Controller . Назовем его CharacterController . В окне Hierarchy выделим нашего персонажа Character и перетащим CharacterController в поле Controller компонента Animator :

    Кликнем дважды по CharacterController - откроется новое окно Animator . В нем мы будем создавать различные состояния анимации (покой, бег, прыжок) и задавать условия перехода между ними. Для создания непосредственно анимаций нам нужно окно Animation . Если оно у вас еще не отображается его можно включить из главного меню Unity (Window - Animation ). Теперь выберем нашего персонажа Character в окне Hierarchy , а в окне Animation нажмем кнопку для создания новой анимации и выберем Create New Clip . На скриншоте ниже я отметил эту кнопку красной окружностью:

    В стандартном диалоге сохранения файла сперва создадим папку Animations , а в нее сохраним наш файл анимации, назвав его Idle .

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

    Осталось всего пара шагов. Переходим в папку Sprites , разворачиваем спрайт Idle , выделяем первое изображение Idle_0 , зажимаем шифт и выделяем последнее изображение Idle_7 . Все выделенные изображения переносим мышью на окно Animation . Зададим значение Sample равное 10 - этот параметр означает количество кадров анимации в секунду. Как известно, для хорошей анимации необходимо, чтобы она отображалась со скоростью не менее 24 кадров в секунду, однако, в нашем случае анимация состоит из довольно маленького числа кадров и при значении 24 она будет отображаться слишком быстро.

    Запустим игру! Если все сделано правильно, наш Капитан Коготь должен стоять на платформе, дышать, и вилять хвостом.

    На этом пока все. В следующий раз поговорим о реализации бегущего вправо-влево персонажа и соответствующей анимации.



    © 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows