В этом уроке по разработке 2D игры на Unity мы оживим статические элементы в нашей игре, добавив в них анимацию.
Хотя мы уже сделали нашу игру (и даже научились ее компилировать под разные устройства в предыдущем уроке), есть еще несколько способов, чтобы сделать ее лучше. Именно поэтому и родилась эта дополнительная глава.
На текущем этапе есть один аспект, которому нам стоит уделить больше внимания - анимация. Даже если визуальный стиль может оправдать отсутствие анимации (ведь мы используем растрированные рисунки), мы все равно можем их анимировать. Давайте добавим нового врага, супер-босса, и создадим для него эффекты анимации. Анимации в Unity состоят из нескольких элементов:
- Несколько анимационных клипов, определяющие ключевые кадры для каждого анимированного свойства.
- Контроллер анимации, определяющий порядок и переход клипов объекта (или префаба).
Спрайт состоит из нескольких изображений: тело, глаза и пр. Сохраните рисунок ниже, он нам понадобится.
- Импортируйте изображение в Unity.
- Установите "Sprite Mode" значение "Multiple" в "Inspector".
- Нажмите на кнопку "Sprite Editor"
Используйте функцию автоматического разрезания (32 должно идеально подойти):
Не забудьте "Применить" нарезки.
Супер-босс
Босс выполнен из четырех частей:
Чтобы иметь правильную конфигурацию, создайте пустой объект игры. Тогда:
- Назовите его "Boss".
- Добавьте "Rigidbody 2D" без гравитации/постоянных углов.
- Добавьте "Box collider 2D" с размерами
(6, 6)
.
- Установите его масштаб
(0.5, 0.5, 1)
.
- Этот объект ничего не отображает. Поэтому здесь и нет "Sprite Renderer".
Создать 4 пустых игровых объекты, как дети объекта "Boss". Для каждого из них добавьте "Sprite Renderer" и выберите соответствующее изображение (тело, глаза или рот). Измените их положение, чтобы получить что-то вроде этого:
Используя также это в качестве иерархии:
Например, левый глаз игрового объекта позиционируется с помощью мыши в редакторе. Вот что у нас:
Совет: У нас есть только один спрайт для глаз. Мы просто перевернем другой спрайт с помощью зеркального отражения. Для этого в Unity установите значение масштаба на противоположное. В частности, мы установим масштаб глаз равным (-1, 1, 1)
. Вы можете использовать этот простой совет везде и даже у свойства y
(зеркальное отражение по вертикали).
Установите объект "тело" немного глубже, чем остальные, вот так: (0, 0, 1)
. 3D-вид покажет наши слои:
Используя объект со множеством подспрайтов, мы можем манипулировать ими отдельно. Сохраните объект "Boss", как префаб. Теперь мы готовы анимировать его!
Старая школа анимации предлагает нам анимировать объект с помощью одного листа спрайтов и изменять положение всего изображения каждые N секунд.
Этот способ также работает в Unity, но это не цель этой главы..
Анимационные клипы
Мы собираемся создать несколько клипов для определения состояния нашего босса:
- Idle — просто плавающий вокруг.
- Attack — запуск снарядов.
- Hit — попадания выстрела.
Для этого урока мы опишем первую анимацию настолько детально, насколько это возможно. Затем мы отобразим остальные с помощью гиф-анимации, а вы получите задание воспроизвести их. Это хороший способ узнать, как управлять инструментом анимации. И, конечно, сделать их лучше. :)
Совет: Когда вы работаете над анимацией, делайте это в пустой сцене. Таким образом, вы можете четко видеть, что происходит и ни на что не будете отвлекаться. Здесь мы будем работать в сцене под названием TestAnimations
. Эта сцена как раз для дизайнеров и никогда не должна быть включена или запущена в окончательном проекте.
Idle - анимация. Создаем новый клип
Open the "Animation" window (not "Animator"!):
Новое окно должно отображаться:
Выберите объект boss в вашей сцене (экземпляр, если это необходимо, вы не можете работать непосредственно на Prefab
). Теперь создайте новый клип. Опция доступна в списке анимация:
Создайте папку "Animations" и сохраните новый клип как "Boss_Idle". Клип будет выбран в анимационной панели.
Новый клип: На самом деле, с помощью кнопки «Создать новый клип", с точки зрения анимации, Unity делает три вещи. Во-первых, он создает "Аниматор-Контроллер" для выбранного игрового объекта (в данном случае - это босс). Потом он добавляет к этому аниматору «Анимацию». «Аниматор» также добавляется к игровому объекту в качестве компонента, указывающего на «Аниматор-Контроллер». Если у игрового объекта уже есть «Аниматор», к нему просто добавляется анимация. Загляните в папку «Анимации»: рядом с анимацией "Boss_Idle" вы увидите аниматор “Boss”. Мы будем говорить об этом чуть позже, пока не трогайте его.
Добавление ключевых кадров
Для начала работы над клипом, нажмите на кнопку "Record" (красная точка) в верхнем левом углу вкладки "Анимация". Теперь, все, что вы будете делать в сцене для нашего объекта (босса) будет записываться в качестве ключевого кадра анимации.
Внимание: Клик на линейке времени включит кнопку "Запись". Будьте осторожны! Этот способ можно использовать для ускорения работы: просто кликните на время и добавьте необходимые изменения (запись начнется, когда на линейке появится красный маркер).
Ключевой кадр - это набор значений , относящихся к определенному моменту во времени.
Чтобы добавить ключевой кадр:
- Вы можете нажать на кнопку "Запись"
- Выберите время, нажав на линейке времени. Следует перевести селектор (красная линия).
Выберите объект "Босс" в вашей сцене. В 0:30
измените поворот на (0, 0, 30)
.
Поворот: Во вкладке "Сцена" (Scene) если вы наведете указатель на уголок рамки выделенного объекта, то вы увидите как изменился указатель мыши. Удерживая и перемещая мышь, вы можете изменить угол поворота выбранного объекта.
Вы можете видеть, что ключевой кадр создан:
Горячие клавиши: клавиша alt
может быть использован для перемещения по линейке времени. Колесо мыши можно использовать для увеличения или уменьшения масштаба, наведя курсор на необходимый объект и прокручивая его вверх или вниз.
Если вы нажмете кнопку "Play" во вкладке "Анимация" (Animation) то, вы увидите анимацию в панелях "Игра" (Game) или "Редактор" (Editor):
Начнем! Наш Босс выглядит глупо, поэтому мы добавим два новых ключевых кадра:
1:00
- "Boss" object rotation of (0, 0, 30)
.
1:30
- "Boss" object rotation of (0, 0, 0)
.
Теперь, анимация отображается плавно (потому что вращение происходит одинаково в начале и в конце).
Если вы кликните на значение ключевого кадра в редакторе, Unity перейдет в режим записи и выделит изменяемые свойства красным в «Инспекторе».
Изменение свойство объекта "Boss": Если вы измените свойство родительского объекта (объект "Boss" в данном случае), будьте осторожны, особенно со свойством "Позиция" ("Position"). Например, если вы измените свойство "Position" для объекта "Boss", его положение в сцене заменится положением в анимации каждый раз, когда вы будете ее проигрывать. Он может блокировать объект. В большинстве случаев вам нужно будет изменить детские свойства, а не сам контейнер. Здесь мы работаем с родителем, потому что нам надо, чтобы все вращалось вместе. Но может быть, нам нужен еще и пустой родительский объект, к которому не применяется анимация.
Играtv с кривыми
Между каждым ключевым кадром Unity использует линейную интерполяцию для вывода промежуточных значений. Если мы говорим:
- Время
0:00
, значение 0
.
- Время
0:30
, значение 30
.
Тогда Unity может вывести:
Тем не менее, вы можете применить нелинейную интерполяцию (например, начинается быстро и заканчивая медленно). Для этого есть два решения: можно добавить другие ключевые кадры между ними, или поиграть с Curves. Это специальная вкладка, которую можно переключать в левом нижнем углу вкладки "Анимация":
Сейчас наша нынешняя простоя анимация выглядит как обычная синусоида:
Мы можем поиграть с кривой путем перетаскивания точек. Он будет обновлять ключевые кадры и связанные с ними значения. Например, если мы внесем немного беспорядка:
Анимация выглядит уже по-другому: она воспроизводится быстрее, с паузами между циклами.
Tweaks
Мы просто сделали анимацию, используя вращение, но вы можете обновить все свойства объекта и его детей. Например:
- Вы можете обновить позицию (не делайте этого на контейнере).
- Изменить спрайт (из "Sprite Renderer").
- Добавить и удалить детей.
- Включить или выключить компоненты.
- Обновить размер коллайдера, чтобы он соответствовал анимации.
Теперь, настало время для экспериментиров! Вот что у вас в конце концов должно получиться:
Анимация атаки и удара
Для этих анимаций мы покажем что вы можете достичь, но мы рекомендуем вам весело провести время и сделать свои собственные. Это хорошая возможность проверить, что вы узнали раньше. Просто убедитесь, что имя клипов - "Boss_Attack" и "Boss_Hit". In your "Boss" Prefab
, добавьте нового ребенка спрайта "Bonus". Этот объект будет служить для отображения дополнительного изображения, когда это потребуется. Большую часть времени оно будет скрыто (например, в режиме ожидания анимации).
Атака
Ключевые кадры должны выглядеть следующим образом:
Посмотрим на детей "Mouth" (другое изображение) and "Bonus" (включен).
Удар
В зацикленном виде эта анимация выглядит странно, но наша цель – быстрая анимация, которая проигрывается всего один раз в ответ на выстрел игрока.
Ключевые кадры:
Чтобы отключить цикл, нажмите на анимацию "Boss_Hit" на панели "Проект" ("Project"). Затем, снимите флажок "Loop Time". На первый взгляд может показаться что ничего не изменилось. Запустите игру и смотрите в окно "Аниматор" ("Animator"), чтобы увидеть разницу.
Спец-слой
Мы рекомендуем использовать выделенный слой для работы с анимацией. Это очень удобно:
- Вкладка "Сцена" (Scene) находится рядом с вкладкой "Анимация". Вы можете нажать на спрайт, чтобы выбрать и изменить его. Если анимация записывается, вы увидите новый ключ на линейке времени после каждого изменения.
- В режиме "Игра" всегда можно отобразить анимацию, нажав на кнопку "Play" в режиме "Animation" (без запуска игры).
Не забудьте сохранить макет чтобы использовать его в будущем.
Мы сделали несколько анимационных клипов для нашего нового врага. Но сейчас, они нигде не используются. Действительно, клип просто слой, содержащий информацию о том как оживить объект. Нам потребуется "Аниматор" (Animator). "Animator" является компонентом, который вы перенесли на объект, ссылающийся на контроллер Аниматор (Animator Controller). "Контроллер Аниматор" - контроллер, который позволяет выполнять работу с анимациями в аниматоре - добавлять анимации, слои, и т.д. Давайте посмотрим как им пользоваться.
Аниматор (Animator)
Вы, возможно, уже обратили внимание что объект "Boss", над которым мы работали, автоматически получил новый компонент: "Аниматор". В то же время, в папку "Animations" был добавлен новый файл, названный так же, как Ваш объект. Это контроллер Аниматор.
Теперь взглянем на свойство "Controller" компонента "Animator":
Файл "Boss" является контроллером. Вы можете проверить это, кликнув на поле контроллера — выделится прикрепленный файл:
С помощью этого контроллера мы будем определять, как и когда Unity должно проиграть анимационные ролики. В принципе, компонент "Аниматор" - просто связь между объектом и контроллером. Этот компонент можно извлечь и манипулировать им с помощью кода. Если ваш префаб "Boss" не имеет компонент "Аниматор", добавьте его вручную и перетащите контроллер "Boss" внутрь свойства.
Компонент "Аниматор" имеет и некоторые другие параметры. "Apply Root Motion" следует отключить при использовании анимации, как мы делаем в этой статье. Но здесь это не важно, потому что у нас очень простой объект без гравитации.
Внутри аниматора
Теперь мы должны открыть окно, называемое "Аниматор" (Animator) (не спутайте с "Анимация" (Animation))! Для этого Вы можете дважды щелкнуть по файлу контроллера ("Animations/Boss"), чтобы открыть контроллер, или вы можете найти его в меню "Окно" (Window):
Вы должны получить что-то вроде этого:
Вы можете видеть, что у нас есть состояния - states (прямоугольники), созданные автоматически с нашими клипами, плюс один специальный по имени "Any State". Помните, когда вы использовали кнопку "Создать новый клип" во вкладке "Анимация", Unity при этом добавило состояние в контроллере объекта, связанное с созданным Вами файлом анимации. Пройдитесь по каждому состоянию аниматора и переименовать их, удалив префикс "Boss_":
"Аниматор-контроллер" – это машина с конечным числом состояний. Каждое состояние может быть анимацией, и вы можете определить переходы между ними. Переход рассказывает Unity, когда и почему она должна перейти от одного состояния в другое.
На этой картинке, мы создали связь между двумя состояниями. Чтобы проанимировать объект с помощью анимации "Hit", сначала нам нужно использовать состояние "Idle". Мы сосредоточимся немного больше на переходах чуть позже, а сейчас давайте посмотрим на три разных типа состояний.
1. Дефолтное состояние
Оранжевое состояние является дефолтным: это изначальное состояние, в котором запускается игра.
В этом случае, "Idle" состояние по-умолчанию одно (если это не так, щелкните правой кнопкой мыши и выберите "Установить по умолчанию" (Set As Default)). Это означает, что, когда игра началась, объект "Boss" будет автоматически воспроизводить "холостую" анимацию (бесконечно, если включить "Loop Time" в "Inspector" — как и должно быть в данной игре).
2. "Любое состояние"
Зеленое состояние, которое называется "любое состояние" – особый случай.
Это хороший способ упростить наш контроллер. Как можно догадаться по названию, оно представляет собой каждое состояние в заданный момент времени. В контроллере босса это состояние одновременно представляет собой состояния "Idle", "Hit" и "Attack". Поясним это на нескольких примерах. Предположим, мы используем следующую машину с конечным числом состояний:
Для того, чтобы наступило событие "Jump" (прыжок), вы должно выполняться "Walk" (ходить), затем "Run" (Выполнить) и лишь потом "Jump". Это означает, что анимация "Jump" не будет воспроизводиться, если ваш объект до этого не находится в состоянии "Run".
Это не идеально, не так ли? Мы должны переходить в состояние "Jump", когда находимся в состоянии "Walk" тоже! Хорошо, давайте попробуем сделать это:
Отлично, теперь мы можем перейти в "Jump" из состояний "Walk" и "Run". Тем не менее, если вы добавите несколько новых состояний, то вам потребуется создать еще переходы в "Jump" от каждого состояния. Решение этой задачи заключается в использовании "Any State":
Благодаря этому контроллеру, «любое состояние» может перейти в "Jump". Разве это не гениально?
3. Нормальное состояние
Серые состояния являются нормальными и содержат одну анимацию либо не содержат ее вообще.
На левом нижнем углу вкладки "Аниматор", вы можете найти список параметров. Эти параметры используются для условий переходов. Подробнее об этом ниже.
В верхнем левом углу, вы можете увидеть слои. This is a way to have multiple state machines for one object. Мы не будем использовать эту функцию, в этом руководстве.
И, наконец, кнопка "Auto live Link" в правом верхнем углу, который позволяет видеть в режиме реального времени состояния, которых в настоящее время проигрываются. Оставьте ее включенной.
Добавление параметров
Параметр – это значение или триггер для нашей машины с конечным числом состояний. В дальнейшем мы будем использовать их в условиях наших переходов. Доступно 4 типа параметров:
Int
— просто целое число.
Float
— просто вещественное число.
Bool
— true
или false
значение.
Trigger
— флаг, который остается включен, пока он не используется. Затем он будет снят.
Числа понадобятся нам для особых случаев вроде горизонтальной или вертикальной скорости. Вам можете понадобиться другая анимация для ходьбы или бега, но все они зависят от скорости движения игрока, которая выражается с помощью определенного параметра.
Для нашей игре, давайте добавим два новых параметра:
- "Hit" - trigger
- "Attack" - boolean
(К сожалению, редактор внешне не различает триггеры и булевские значения)
Теперь, давайте посмотрим зачем они нам.
Переходы
Переход является связующим звеном между двумя состояниями. Он определяет, как именно одно из них должно превращаться в другое.
1. "Idle to Attack"
Чтобы создать переход, нажмите правой кнопкой мыши на состоянии источника. Давайте сначала проделаем это для "Idle to Attack": щелкните правой кнопкой мыши на состоянии "Idle", а затем выберите "Make transition":
- Теперь кликните на состояние назначения:
Вот и все!
Вы можете выбрать переход, нажав на ссылку."Инспектор" (Inspector) покажет много интересных параметров, в частности начальные условия:
Exit Time: Условие "Exit Time" – дефолтное условие для перехода. Оно значит, что переход может быть осуществлен, когда закончится исходная анимация.
Это то, что мы будем редактировать. Измените "Exit Time" для параметра "Attack", который мы определили ранее.
Это условие означает: "Если значение Attack
true
, то воспроизвести анимацию "Attack". Точно так же, добавить переход между "Attack» и "Idle" с условием "Attack
- false
".
Это означает, "Если значение Attack равно false
, то остановить анимацию "Attack" и вернуться в режим ожидания".
Как видите, нам пришлось определить значения для обоих переходов. В противном случае контроллер не вернулся бы к состоянию "Idle" после атаки.
Мы сделаем почти то же самое для Idle анимации.
2. "Idle to Hit"
Вы еще не забыли про "Any State"? Сейчас он нам понадобится. Сделайте два новых подключения:
- От "Any State" к "Hit", условие
Hit
.
- От "Hit" к "Idle", условие
Exit Time
.
Если установлен триггер "Hit", мы проиграем один раз анимацию "Hit" и возвращаемся к "Idle".
"Any State" придется здесь как раз кстати, поскольку триггером для Hit
являются такие состояния босса, как "Idle" или "Attack". Вместо того, что определять оба состояния, мы просто используем "Any State".
Как видите, когда вы используете триггер, не нужно указывать значение. Действительно, триггер - это просто способ сказать контроллеру: "Если состояние действительно
- делай переход".
Конечный график
График нашей анимации должен выглядеть так:
Последнее, что нам понадобится – это код, с помощью которого все эти переходы происходили бы в самой игре (иначе аниматор останется в состоянии "Idle").
График анимации: Создание графика в аниматоре – вовсе не точная наука. В зависимости от того, какой код вы используете, чего хотите добиться или в какой последовательности выполняете те или иные действия, этот алгоритм может меняться. Например, в нашем случае мы могли бы осуществить переход к атаке из "Any State". Но поскольку мы используем всего три короткие анимации, это не имеет особого значения. По мере того, как ваш график будет расти, вам придется принимать решения, которые повлияют на вашу игру.
А где же Boss?
Прежде чем перейти к действительно интересному вопросу, нам нужно позаботиться о том, чтобы в игре был босс.
Не будем затягивать, ведь эта глава все-таки посвящена анимациям.
- Добавьте "HealthScript" в Боссу, и задайте ему много очков здоровья (например,
50
).
- Добавить "MoveScript". Для хорошего перемещения попробуйте скорость
(5, 5)
.
Снаряд
Нам нужен новый снаряд, которым Босс будет атаковать игрока. Продублирйте "EnemyShot1" и измените изображение на новое:
Далее установите масштаб (0.3, 0.3, 1)
и сохраните как новый префаб. У Вас должно получиться что-то вроде этого:
Оружие
Точно так же, как мы делали с "Poulpi", присоедините к боссу ребенка оружия (пустой игровой объект с "WeaponScript").
Отлично. Теперь напишем скрипт для Босса. Назовем это "BossScript".
using UnityEngine;
///
/// Общее поведение для врагов
///
public class BossScript : MonoBehaviour
{
private bool hasSpawn;
// Параметры компонентов
private MoveScript moveScript;
private WeaponScript[] weapons;
private Animator animator;
private SpriteRenderer[] renderers;
// Поведение босса (не совсем AI)
public float minAttackCooldown = 0.5f;
public float maxAttackCooldown = 2f;
private float aiCooldown;
private bool isAttacking;
private Vector2 positionTarget;
void Awake()
{
// Получить оружие только один раз
weapons = GetComponentsInChildren();
// Отключить скрипты при отсутствии спауна
moveScript = GetComponent();
// Получить аниматор
animator = GetComponent();
// Получить рендереры в детях
renderers = GetComponentsInChildren();
}
void Start()
{
hasSpawn = false;
// Отключить все
// -- Collider
collider2D.enabled = false;
// -- Движение
moveScript.enabled = false;
// -- Стрельба
foreach (WeaponScript weapon in weapons)
{
weapon.enabled = false;
}
// Дефолтное поведение
isAttacking = false;
aiCooldown = maxAttackCooldown;
}
void Update()
{
// Проверим появился ли враг
if (hasSpawn == false)
{
// Для простоты проверим только первый рендерер
// Но мы не знаем, если это тело, и глаз или рот ...
if (renderers[0].IsVisibleFrom(Camera.main))
{
Spawn();
}
}
else
{
// AI
//------------------------------------
// Перемещение или атака.
aiCooldown -= Time.deltaTime;
if (aiCooldown <= 0f)
{
isAttacking = !isAttacking;
aiCooldown = Random.Range(minAttackCooldown, maxAttackCooldown);
positionTarget = Vector2.zero;
// Настроить или сбросить анимацию атаки
animator.SetBool("Attack", isAttacking);
}
// Атака
//----------
if (isAttacking)
{
// Остановить все движения
moveScript.direction = Vector2.zero;
foreach (WeaponScript weapon in weapons)
{
if (weapon != null && weapon.enabled && weapon.CanAttack)
{
weapon.Attack(true);
SoundEffectsHelper.Instance.MakeEnemyShotSound();
}
}
}
// Перемещение
//----------
else
{
// Выбрать цель?
if (positionTarget == Vector2.zero)
{
// Получить точку на экране, преобразовать ее в цель в игровом мире
Vector2 randomPoint = new Vector2(Random.Range(0f, 1f), Random.Range(0f, 1f));
positionTarget = Camera.main.ViewportToWorldPoint(randomPoint);
}
// У нас есть цель? Если да, найти новую
if (collider2D.OverlapPoint(positionTarget))
{
// Сбросить, выбрать в следующем кадре
positionTarget = Vector2.zero;
}
// Идти к точке
Vector3 direction = ((Vector3)positionTarget - this.transform.position);
// Помните об использовании скрипта движения
moveScript.direction = Vector3.Normalize(direction);
}
}
}
private void Spawn()
{
hasSpawn = true;
// Включить все
// -- Коллайдер
collider2D.enabled = true;
// -- Движение
moveScript.enabled = true;
// -- Стрельба
foreach (WeaponScript weapon in weapons)
{
weapon.enabled = true;
}
// Остановить основной скроллинг
foreach (ScrollingScript scrolling in FindObjectsOfType())
{
if (scrolling.isLinkedToCamera)
{
scrolling.speed = Vector2.zero;
}
}
}
void OnTriggerEnter2D(Collider2D otherCollider2D)
{
// В случае попадания изменить анимацию
ShotScript shot = otherCollider2D.gameObject.GetComponent();
if (shot != null)
{
if (shot.isEnemyShot == false)
{
// Stop attacks and start moving awya
aiCooldown = Random.Range(minAttackCooldown, maxAttackCooldown);
isAttacking = false;
// Изменить анимацию
animator.SetTrigger("Hit");
}
}
}
void OnDrawGizmos()
{
// Небольшой совет: Вы можете отобразить отладочную информацию в вашей сцене с Гизмо
if (hasSpawn && isAttacking == false)
{
Gizmos.DrawSphere(positionTarget, 0.25f);
}
}
}
Мы разделим объяснение кода на две части: одна будет про анимацию, другая про Босса.
- Мы устанавливаем значение булевского параметра "Attack" в аниматоре для первого кадра в фазе атаки. Помните о контроллере и переходах? Это действие просто установит значение для параметра и сработает в качестве триггера для перехода в следующее состояние:
// Установить или сбросить анимацию атаки
animator.SetBool("Attack",isAttacking);
- Мы вызваем параметр "Hit", когда игрок попадает в босса:
animator.SetTrigger("Hit");
Итак, с анимацией разобрались, давайте теперь займемся Боссом. ННадо признать, наш Босс довольно туповат: он просто то движется, то стреляет. То движется, то стреляет ... У нас есть булевское значение, которое показывает, в каком из этих состояний он находится (isAttacking
). В фазе движения босс рандомно выбирает видимую точку в поле зрения и начинает двигаться в ее сторону. Достигнув этой точки (если она находится в границах коллайдера), он меняет направление движения. Мы сделали эту точку видимой в режиме отладчика:
Совет: OnDrawGizmos
- это очень полезный метод для отображения на сцене отладочной информации из скрипта с помощью класса Gizmos
. Здесь мы показываем позицию, где Босс появляется в виде шара. Вы можете увидеть эту сферу в панели редактора или во вкладке "Game" (если вы включили "Gizmos").
Мы переходим из одной фазы в другую с помощью простого таймера(aiCooldown
). Когда он достигает отметки 0, мы заменяем одну фазу другой и устанавливаем новое случайное значение. Но если в босса стреляют, мы заставляем его двигаться (он уходит из зоны атаки и находит для себя новую точку). Поэтому переход в состояние "Hit" происходит из состояние "Any State" в аниматоре. Наконец, когда происходит спаун босса, скроллинг камеры и игрока устанавливается на 0
. Таким образом, игра останавливается и говорит вам, что нужно победить врага чтобы двигаться дальше (даже если ничего не происходит после демо, вы понимаете, что нужно сделать).
Итоговый результат
Пришло время добавить нового врага в сцену "STAGE1". Поставьте Босса после всех ваших врагов:
Если вы хотите проверить его в действии, Вам придется добавить здоровье для игрока, в противном случае это будет немного ... хардкор. :) Теперь у вас есть анимированный Босс, которого Вам нужно победить!
Если Вы выберите игровой объект в "Иерархии" (Hierarchy) и откройте окно "Аниматор" (Animator), вы сможете увидеть "Аниматор Controller" в действии:
Бонусы - шмонусы
К сожалению, мы только поверхностно рассмотрели то, что вы можете сделать с аниматором. Будем надеяться, что остальное будет довольно просто для понимания. Давайте посмотрим на другие аспекты. Представьте, что у вас есть...
И вы никак не можете контролировать этот процесс. Для этих случаев Unity предоставляет функцию "Sub-State Machine". Щелкните правой кнопкой мыши на графике и выберите "Create Sub-State Machine".
Затем дважды щелкните на новом состоянии:
Так вы создадите в своей машине новый график с состояниями "Any State" и "(Up) Base Layer". Он работает точно так же, как и основной график, но теперь вы можете присоединить подсостояние к основному состоянию с помощью "(Up) Base Layer".
Вот как это выглядит для состояния "Jump":
Blend tree – особое состояние, которое объединяет несколько клипов на основе единого параметра. Например, вы можете иметь клипы "Walk", "Run" и "Sprint". Использовав blend tree и параметр скорости, вы подскажете аниматору, как объединить эти три клипа в зависимости скорости.
Выбор перехода, solo и mute
Если у вас есть несколько переходов для одного и того же состояния, вы можете выбрать одно из них, выбрав состояние и кликнув на его переходы:
Посмотрите на "Mute" и "Solo" чекбоксы. Их задача - изолировать переходы от остальных.
- Если вынажмете на "Mute", аниматор проигнорирует этот переход .
- Если вынажмете на "Solo", аниматор будет проигрывать только этот переход .
Это действительно полезно когда вы хотите проверить определенное состояние или точность перехода между ними.
Atomic
По умолчанию для всех переходов установлен параметр "Atomic". Это означает, что переход не может быть прерван. Вы можете отключить это поведение, сняв этот параметр:
Финиш!
Теперь мы знаем как создавать анимационные клипы и использовать их в качестве аниматора! Наш бонусный урок о анимации закончился!