Анимации Как и в XAML, анимации создаются выполнением различных действий в ключевых кадрах. Я мог бы легко посвятить целую статью одним только анимациям в Unity, но буду краток из-за нехватки места. В Unity есть две системы анимации: устаревшая и более новая — Mecanim. В устаревшей системе используются файлы анимации (.ani), а в Mecanim — состояния, управляющие тем, какой файл анимации воспроизводится.
В двухмерной графике по умолчанию применяется Mecanim. Самый простой способ создать анимацию — перетащить изображения в сцену и разрешить Unity создать анимацию за вас. Для начала я перетащил некоторые отдельные спрайты в Unity, а та в свою очередь создала за меня несколько вещей. Прежде всего она создала игровой объект с компонентом рендера спрайтов (sprite renderer component) для рисования спрайтов. Затем — файл анимации. Вы можете увидеть это, перейдя в Window | Animator и выделив свой игровой объект. Аниматор показывает назначенный файл анимации, который в моем случае содержит шесть ключевых кадров, поскольку я перетащил в сцену шесть изображений. Каждый ключевой кадр контролирует один или более параметров в каком-либо компоненте; здесь изменяется свойство Sprite компонента Sprite Renderer. Анимации — это не более чем отдельные изображения, показываемые с некоей частотой, воспринимаемой глазом как движущиеся картинки.
Далее Unity создала компонент Animator в игровом объекте, как показано на рис. 9.
.png)
Рис. 9. Компонент Animator, указывающий на контроллер
Этот компонент указывает на простой конечный автомат, называемый контроллером анимации. Это файл, создаваемый Unity, который просто показывает состояние по умолчанию; иначе говоря, он всегда находится в состоянии «idle» («простаивает»), так как это единственное доступное состояние. Это состояние простоя ничего не делает, а просто указывает на мой файл анимации. На рис. 10 представлены реальные данные ключевых кадров на временном графике.
{Рисунок: здесь нужно перевести надпись Each keyframe changes the image — Каждый ключевой кадр выполняет смену изображения}
_mini_oszone.jpg)
Увеличить
Рис. 10. Анимационные данные в простое
Может показаться, что для подготовки анимации требуется много усилий. Однако мощь конечных автоматов в том, что вы можете управлять ими, задавая простые переменные. Вспомните: состояние не делает ничего — только указывает на файл анимации (хотя в 3D можно изощряться и делать такие вещи, как смешивание анимаций).
Затем я взял больше изображений, что создать анимацию run (run animation) и перетащил их на свой игровой объект Yeti. Так как у меня уже есть компонент аниматора в этом объекте, Unity просто создает новый файл анимации и добавляет новое состояние «run» («выполняется»). Я могу просто щелкнуть правой кнопкой мыши состояние idle и создать переход к run. При этом появляется стрелка между состояниями idle и run. Далее можно добавить новую переменную Running, использовать которую очень легко: вы просто щелкаете стрелку между состояниями и изменяете условие использования этой переменной, как показано на рис. 11.
.png)
Рис. 11. Смена состояний из idle в run
Когда Running становится равной true, анимация idle сменяется анимацией run, что означает лишь воспроизведение файла анимации с состоянием run. Вы можете легко контролировать эти переменные в коде. Если вы хотите запустить свою анимацию run инициацией состояния run при щелчке кнопки мыши, то можете добавить код, приведенный на рис. 12.
Рис. 12. Смена состояния программным способом
private Animator _animator;
void Awake()
{
// Кешируем ссылку на компонент Animator
// из этого игрового объекта
_animator = GetComponent<Animator>();
}
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
// Это заставит контроллер анимации перейти
// из состояния idle в состояние run
_animator.SetBool("Running", true);
}
}
В моем примере я использовал отдельные спрайты для создания анимации. Однако довольно часто используют ленту спрайтов (sprite sheet) — один файл более чем с одним изображением в нем. Unity поддерживает ленты спрайтов, так что достаточно сообщить Unity, как разделить на части ваш спрайт, а затем включить эти части в вашу сцену. В этом случае от вас потребуется выполнить ряд операций: сменить в свойствах спрайта Sprite Mode с Single на Multiple и открыть Sprite Editor, который потом сможет автоматически поделить спрайт и применить изменения, как показано на рис. 13. Наконец, вы раскрываете спрайт (в режиме просмотра проекта на значке спрайта есть небольшая стрелка), выделяете полученные спрайты и перетаскиваете их в свою сцену, как обычно.
.png)
Рис. 13. Создание ленты спрайтов
Анимация может быть делом сложным, пока вы не поймете систему. Подробности см. в моем блоге на channel9 или один из многих превосходных ресурсов на сайте обучения Unity.
Конец уровня Когда игрок доходит до конца уровня, можно ограничиться просто коллайдером, работающим как триггер, и позволить игроку попасть в эту зону. После этого вы загружаете следующий уровень или перезагружаете текущий:
void OnTriggerEnter2D(Collider2D collider)
{
// Если игрок попадает на триггер
if (collider.gameObject.tag == "Player")
{
// Перезагружаем текущий уровень
Application.LoadLevel(Application.loadedLevel);
// Вместо этого можно было бы
// передать имя сцены для загрузки:
// Application.LoadLevel("Level2");
}
}
Игровой объект и его соответствующие свойства показаны на рис. 14. Заметьте, что высота коллайдера достаточно велика, чтобы игрок не мог перепрыгнуть через него, и, кроме того, этот коллайдер настроен как триггер.
.png)
Рис. 14. Игровой объект и его свойства
Ход игры (game play) В просто 2D-игре вроде этой поток управления довольно прямолинеен. Игрок начинает игру. Гравитация абсолютно твердого тела заставляет персонаж в игре упасть. У персонажа и платформы есть по коллайдеру, поэтому персонаж останавливается. Считывается сенсорный ввод, от клавиатуры и мыши, что приводит к перемещению игрового персонажа. Игрок перепрыгивает между платформами с помощью rigidbody.AddForce, который заставляет персонаж прыгнуть, и перемещается влево и вправо за счет считывания Input.GetAxis("Horizontal") и его применения к rigidbody.velocity. Игрок собирает грибы, которые являются коллайдерами, настроенными как триггеры. Когда игрок касается их, они увеличивают счет и разрушаются. Как только игрок доходит до финала уровня, срабатывает триггер, перезагружающий текущий уровень. Здесь следовало бы добавить большой коллайдер под землей, чтобы обнаруживать, когда игрок сваливается с платформы, и просто перезагружать уровень.
Заготовки (prefabs) Повторное использование важно как в кодировании, так и в дизайне. Назначив своим игровым объектам несколько компонентов и настроив их, вы будете часто использовать их снова и снова в рамках одной сцены или даже нескольких сцен либо игр. Вы можете создать другой экземпляр игрового объекта в сцене, но также можете создать экземпляр заготовки, которой пока нет в вашей сцене. Возьмем, к примеру, платформы и их коллайдеры. Если вы хотите повторно использовать их в других сценах, то, увы, на данный момент это невозможно. Но, создав заготовки, вы получаете нужную возможность. Просто перетащите любой игровой объект из иерархии обратно в папку проекта, и будет создан новый файл с расширением .prefab, содержащий любые дочерние иерархии. Теперь вы можете перетаскивать этот файл в другие сцены и повторно использовать его. Исходный игровой объект теперь оказывается соединенным с заготовкой. Обновление файла .prefab обновляет все экземпляры в ваших сценах; кроме того, вы можете оправлять изменения из модифицированной заготовки сцены обратно в файл .prefab.
Щелкнув заготовку, вы увидите содержащиеся в нем игровые объекты, как показано на рис. 15. Если вы внесете здесь изменения, все экземпляры в вашей сцене будут обновлены.
.png)
Рис. 15. Просмотр содержимого заготовки
Заключение
Во всех играх выполняется ряд общих операций. В этой статье я рассказал об основах аркадных игр (игр-платформеров), в который используются коллайдеры, абсолютно твердые тела, анимации, учет текущего счета, базовый вывод текста в GUI и чтение пользовательского ввода для применения силы к игровому персонажу с целью его перемещения. Эти строительные блоки можно повторно использовать в играх самых разнообразных типов. В следующей статье мы обсудим трехмерные игры.
Дополнительные материалы для изучения