Сайт о телевидении

Сайт о телевидении

» » Как делать анимацию для unity 2d. Информационный портал по безопасности

Как делать анимацию для unity 2d. Информационный портал по безопасности

Пролог.
И снова здравствуйте. Это второй урок по созданию RPG на Unity3D. Изначально я хотел написать его не много по другому но планы у меня изменились и пришлось все предумывать. Сначала задумывалось делать 2 камеры с видо от первого лица и от 3, но в итоге я оставил только от третьего. Сегодня я все скрипты покажу вам полностью сразу и постораюсь объяснить малопонятные вещи в коде дабы экономить свое время и ваше.
В прошлом уроке я забыл написать о «build», то есть непосредственно компиляции проекта.По этому мы сделаем это сейчас. Откроем наш проект. Если открылась пустая сцена нажмем «Ctrl+o» и откроем сцену которую мы делали на прошлом уроке. Нажмем «Ctrl+Shift+b» и в открывшемся окне нажмем «Add Current». Это поставит наше меню в список компилирования и даст ему порядковый номер. При открытии компилированного проекта первой открывается сцена под номером 0. Если нажмем «Build And Run» наш проект скомпилируется и запустится.

План урока.
1) Импорт персонажа.
2) Передвижение персонажа.
3) Настройка камеры
4) Анимация персонажа.
Импорт персонажа.
Сцена.
Создаем «Terrain» с размерами 200х200. Вешаем какую-нибудь текстуру для удобства отображения. Создадим источник света.
Персонаж
Возьмем заранее подготовленного персонажа с анимациями, я взял из «Asset Store»(«Window>>Asset Store» или Ctrl+9) персонажа с названием Blade Girl NPC. Эта моделька стоит 15$ Она у меня уже есть и я буду использовать именно её. Вы можете там же поискать бесплатные(Среди них есть достойные). или же просто в интернете поискать какие нибудь. В эту модель уже впихнута анимация различных действий, атака, бег и тд. и тп. и даже танец Гангнам Стайл))).


После импорта находим находим в окне «Project» префаб персонажа, у меня он называется «Balde_girl_Prefab» и находится в папке «Blade_girl». Перетаскиваем этот префаб на сцену, и видим наш персонаж, только каойто он большой через чур, это не беда. В инспекторе в пункте «Scale» выставим все по единичке, и все хорошо становиться, моделька стала нормальных размеров, можно работать дальше

«Префаб - это один из типов ресурсов, предназначений для многократного использования и хранящийся в Project View. Префаб может быть вставлен в любое количество сцен и многократно в одну сцену. Когда префаб добавляется в сцену, создаётся его экземпляр. Все экземпляры являются ссылками на оригинальный префаб и фактически его клонами. Независимо от того, как много экземпляров в проекте, при изменении префаба изменяются соответственно и все его экземпляры.»

Нажимаем «Add component>>Physics>>Rigidbody» и «Add component>>Physics>>Capsule Collider». В «Capsule Collider» Выставляем размеры нашей капсулы что бы получилось как на картинке, слегка чуть больше модельки самой.


В «Rigidbody» ставим галочку «Use gravity». Раскрываем вкладку «Constraints» и ставим все 3 галочки на «Freeze Rotation». Это нужно для того что бы наш персонаж не проваливался сквозь землю, не падал на землю если вдруг окажется на неровности и тому подобное.
Программируем персонажа на перемещение.
Создадим c# скрипт «movePlayer».

200?"200px":""+(this.scrollHeight+5)+"px");">using UnityEngine;
using System.Collections;

Public class movePlayer: MonoBehaviour {

Private GameObject player; //Переменна объекта персонажа с которым будем работать.

Public static int speed = 6; //Скорость перемещения персонажа. Запись public static обозначает что мы сможем обращаться к этой переменной из любого скрипта
public static int _speed; //постоянная скорость перемещения персонажа
public int rotation = 250; //Скорость пповорота персонажа
public int jump = 3; //Высота прыжка

Public static bool IsDrawWeapon; //Двоичная переменная, которая будет отвечать достануто ли у нас оружие.
public static float x = 0.0f; //угол поворота персонажа по оси x
void Start () {
IsDrawWeapon = false; //По умолчанию оружие у нас спрятано.
_speed = speed; //Задаем постоянное стандартное значение скорости персонажа
player = (GameObject)this.gameObject; //Задаем что наш персонаж это объект на котором расположен скрипт
}

Void Update () {
if(IsDrawWeapon == true) //Если оружие вытащено
{
speed = _speed * 2; // Меняем скорость передвижени(я это сделал потому что, у этой моделки нету анимаций движения простым шагом с мечом. а понижать скорость анимации у бега получиться не красиво)
{
player.transform.position += player.transform.forward * speed * Time.deltaTime; //Перемещаем персонажа в перед, с заданой скорость. Time.deltaTime ставится для плавного перемещения персонажа, если этого не будет он будет двигаться рывками
}
if(Input.GetKey(KeyCode.S))
{
speed = _speed / 2; //При передвижениии назад снижаем скорость перемещения
}
{
speed = _speed * 2; //Возвращаем cтандартное значение
}
{
}
{
}
{
}

If(Input.GetKey (KeyCode.Tab)) //При нажатии и на кнопку Tab
{
IsDrawWeapon = false; //Мы спрячем наше оружие.
}
}
else if(IsDrawWeapon == false) //Если оружие не спрятано. |||||| Сделано разделение на движения в зависимости от того вытащено ли у нас оружие или нет, потому что персонаж будет перемещаться сразной скорость у меня в этих случаях, как я уже написал из за отсутсвия некоторых анимаций у модельки.
{
speed = _speed;//Скорость в стандартное значение
if(Input.GetKey (KeyCode.LeftShift)) //Если зажать левый Shift
{
speed = _speed * 2; //Увеличиваем скорость перемещения(бег)
}
if(Input.GetKeyUp (KeyCode.LeftShift)) //Если отпустить
{
speed = _speed; //Возвращаем стандартное значение
}
if(Input.GetKey(KeyCode.W)) //Если нажать W
{
player.transform.position += player.transform.forward * speed * Time.deltaTime; //Перемещаем персонажа в перед.
}
if(Input.GetKey(KeyCode.S))
{
speed = _speed / 2;
player.transform.position -= player.transform.forward * speed * Time.deltaTime; //Перемещаем назад
}
if(Input.GetKeyUp (KeyCode.S))
{
speed = _speed; //Возвращаем cтандартное значение
}
if(Input.GetKey (KeyCode.A))
{
player.transform.position -= player.transform.right * speed * Time.deltaTime; //перемещаем в лево
}
if(Input.GetKey (KeyCode.D))
{
player.transform.position += player.transform.right * speed * Time.deltaTime; //перемещаем в право
}
if(Input.GetKey (KeyCode.Space))
{
player.transform.position += player.transform.up * jump * Time.deltaTime; //Прыгаем
}
if(Input.GetKey (KeyCode.Tab)) //при нажатии на кнопку таб
{
IsDrawWeapon = true; //Мы вытащим наше оружие
}
}

//Поворачиваем персонажа. Так как наша переменная x глобальна, из скрипта камеры в неё будем записывать длину на сколько сместился указатель мыши и по оси X и относительно этого будет повернут наш персонаж
Quaternion rotate = Quaternion.Euler (0,x,0); //Создаем новую переменную типа Quaternion для задавания угла поворота
player.transform.rotation = rotate; //Поворачиваем персонаж


Скрипт помещаем на персонажа.
Управление камерой.
Создадим еще один c# скрипт, и назовем его «moveCam»

200?"200px":""+(this.scrollHeight+5)+"px");">codeusing UnityEngine;
using System.Collections;

Public class CamMove: MonoBehaviour {
public Transform target; //Объект за которым летаем(Наш персонаж)
public float distance = 3.0f; //На каком ратоянии от него
public float xSpeed = 125.0f; //Чуствительность по Х
public float ySpeed = 50.0f; //Y Чуствительность
public float targetHeight = 2.0f; //Высота относительно объекта
//Минимальный и максимальный угол поворота Y инче камеру разверет, Дальше у нас будет простая функция для инвертации их в обратные числа
public float yMinLimit = -40;
public float yMaxLimit = 80;
//Максимальное удаление и приближение камеры к персонажу, искорость.
public float maxDistance = 10.0f;
public float minDistance = 0.5f;
public float zoomRote = 90.0f;

Private float x = 0.0f; //Угол поворота по Y?
private float y = 0.0f; //Уго поворота по X?

//Добавляем в меню

Public void Start() {
//переворачивам углы
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;

If(rigidbody)
rigidbody.freezeRotation = true; //Если камера столкнется с физ.объектомона остановиться
}

Public void LateUpdate() {
if (target) {//Если цель установлена(Персонаж)
//Меняем углы согласно положению мыши
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
//Меняем дистанция до персонажа.
distance -= (Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime) * zoomRote * Mathf.Abs(distance);
distance = Mathf.Clamp (distance, minDistance, maxDistance);

Y = ClampAngle(y,yMinLimit, yMaxLimit); //Вызыв самописной функции для ограничения углов поврот
movePlayer.x = x;
//Повернуть камеру согласно поченым данным
Quaternion rotation = Quaternion.Euler(y, x, 0);
transform.rotation = rotation;

//Двигаем камеру и следим за персонажем
Vector3 position = rotation * new Vector3(0.0f, targetHeight+0.5f, -distance) + target.position;

//Следуйщи код нужен что бы камера не проваливалась по ланшафт
RaycastHit hit;
Vector3 trueTargetPosition = target.transform.position - new Vector3(0, -targetHeight,0);
if(Physics.Linecast (trueTargetPosition, transform.position, out hit))
{
float tempDistance = Vector3.Distance (trueTargetPosition, hit.point) - 0.28f;
position = target.position - (rotation * Vector3.forward * tempDistance + new Vector3(0, -targetHeight, 0));
transform.position = position;
}
}

}
//Меняем значения углов
public static float ClampAngle (float angle, float min, float max) {
if(angle < -360)
angle += 360;
if(angle > 360)
angle -= 360;
return Mathf.Clamp (angle, min, max);
}
}


Скрипт кидаем на камеру. Камера должна быть перемещена в префаб персонажа в окне «Hierarchy». А в компоненте скрипта на камере в поле «Target» долже быть помещен наш префаб из окна «Hierarchy».
Анимация
Создадим новый скрипт и назовем его «AnimatePlayer»

200?"200px":""+(this.scrollHeight+5)+"px");">using UnityEngine;
using System.Collections;

Public class AnimatePlayer: MonoBehaviour {

Public void Start ()
{
// Устанавливаем все клипы анимации в режим цикла
animation.wrapMode = WrapMode.Loop;
// Кроме следующих
animation["Attack01"].wrapMode = WrapMode.Once;
animation["jump"].wrapMode = WrapMode.Once;
animation["Skill"].wrapMode = WrapMode.Once;
//У них одиночное выполнение

//Останавливаем выполнение анимаций.
animation.Stop();
}

Public void Update () {
// На основе нажатой клавиши выполняем анимацию
if(movePlayer.IsDrawWeapon == false) //Если оружие не вытащено
{
if (Input.GetAxis("Vertical") > 0.0f) //Проверяем на изминениея позиции персонажа повертикали, если да
{
//Проверяем скорость Передвижения персонажа,
{
animation.CrossFade ("Run00"); //Если зажата клавиша shift, значит грузим анимацию бега
}
else
{
animation.CrossFade("Walk"); //В противном случаее ходьбу
}
}
< 0.0f) //Далее все по анологии
{
if(movePlayer.speed == movePlayer._speed * 2)
{
animation.CrossFade ("B_Run00"); //бег назад
}
else
{
animation.CrossFade ("B_Walk"); //ходьба назад
}
}
else if (Input.GetAxis("Horizontal") > 0.0f)
{
if(movePlayer.speed == movePlayer._speed * 2)
{
animation.CrossFade ("R_Run00"); //бег в право
}
else
{
animation.CrossFade ("R_Walk"); //Шагание в право
}

}
< 0.0f)
{
if(movePlayer.speed == movePlayer._speed * 2)
{
animation.CrossFade ("L_Run00"); //лево
}
else
{
animation.CrossFade ("L_Walk"); //лево
}
}
else if(Input.GetKey (KeyCode.Space)) //если сделан прыжок
{

Animation.Play ("Jump_NoBlade"); //Включаем анимацию прыжка
}
else
{
animation.CrossFade("Idle"); //просто стоим
}
}
else if(movePlayer.IsDrawWeapon == true) //если оружие вытащено
{
if (Input.GetAxis("Vertical") > 0.0f)
{
animation.CrossFade ("Run"); //бег в перед
}
else if(Input.GetAxis("Vertical") < 0.0f)
{
animation.CrossFade ("B_Run"); //назад
}
else if (Input.GetAxis("Horizontal") > 0.0f)
{
animation.CrossFade ("R_Run"); //в право
}
else if(Input.GetAxis("Horizontal") < 0.0f)
{
animation.CrossFade ("L_Run"); //в лево
}
else if(Input.GetKey (KeyCode.Space))
{
animation.Play ("jump"); //Прыжок
}
else
{
animation.CrossFade("AttackStandy"); //просто стоим
}

//Анимация атаки
if (Input.GetMouseButton (0)) //Если нажать маус 1
animation.CrossFade("Attack01"); //Включаем анимацию атаки
if (Input.GetMouseButton (1)) //Если нажать маус 2
animation.CrossFade("Skill"); //Включаем анимацию скила
}
}
}


Скрипт должен быть помещен на персонажа. В окне «Project» создадим папку «Prefab» и перетащим в нее префаб персонажа из окна «Hierarchy» что бы сохранить все на будущее и не повторять все заново.
На сегодня все всем надеюсь моя статья вам будет полезна.


Часть 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 , то вы ув



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

1. Установка

Итак, работа начинается с покупки и установки самого плагина с Asset Store:



Далее добавляем плагин в рабочую область: Window >> Puppet2D

2.Создание скелета. Подготовка

Перед созданием скелета, выстраиваем спрайты на сцене и создаем Layer для персонажа (куда поместим спрайты, я назвала его «Player»):

И Sorting Layer для костей и контроллеров (тут «Bones» и «Controllers»). Попутно выставляем слоя для костей и контроллеров в самом Puppet:

3.Создание скелета

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

Создание начинается с кнопки «Create Bone Tool» (1)

Нажимаем ЛКМ на нужных местах, по окончании - ПКМ или «Finish Bone» (2). Если сначала нажмем на уже существующую кость и создадим от нее еще одну, то та станет костью-родителем.

Для хребтов людей и животных существует кнопка «Create Spline Tool»(3). Помечаем начальную и конечную точку, а показатель (4) - количество костей между данными точками. На концах этих точек автоматически появятся контроллеры. Завершаем сплайн кнопкой «Finish Spline»(5).

В итоге должен получится примерно такой скелет:

4.Создание скелета. Вешаем контроллы

Далее все просто - на конечности вешаем контроллы:

(1) - Контроллер для конечностей (рук, ног)
(2) - Контроллер-родитель
(3) - Контроллер только для поворотов (например, головы)

5.Создание скелета. Привязка спрайтов к скелету

Существует 2 способа привязки:

  • если одному спрайту соответствует одна кость;
  • если одному спрайту соответствуют 2 и больше костей.
В первом случае все очень просто: выбираем нужные кости, выбираем нужный спрайт и жмем кнопку «Parent Object To Bones»:

Во втором придется немного заморочится, ибо нужно конвертнуть спрайт в мэш. Выбираем спрайт и жмем кнопку «Convert Sprite To Mesh»:

Показатель «Type of Mesh»(1) (От 0 до 4) указывает на количество треугольников в полигоне. Чем выше тип, тем их больше.

Следующим шагом будет привязка этого мэша к костям. Выбираем его, выбираем кости и жмем «Bind Smoth Skin»:

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

6. Создание скелета. Корректировка весов

Если объяснить упрощенно, то веса показывают, какая кость гнет какой мэш. Выбираем нужный мэш, затем редактируем, начиная с кнопки «Paint Weights»:

Выбираем нужную кость и там где белый цвет - кость гнет мэш, там где черный - нет:

Выбираем толщину и жесткость кисти и закрашиваем веса с помощью ЛКМ:

Shift + ЛКМ = Смяхчение переломов
Ctrl+ ЛКМ = Стирание весов

Заканчиваем редактирование кнопкой «Finish Edit Skin Weights».

7. Анимация

Заключитальным этапом конечно же будет анимация. Тут уже ваша фантазия неограничена. Двигаем контроллы, выставляем позы и, вуаля, вот наш скелетик уже бегает:

Напоследок добавлю туториал с оффициального YouTube-канала Puppet2D:

Вы можете помочь и перевести немного средств на развитие сайта

Всем добрый день. В относительно недавно вышедшей 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 она будет отображаться слишком быстро.

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

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