Казалось бы, при чём тут Ведьмак?
Сегодняшний пост продолжит тему, поднятую в статье под названием "Unity и Singleton" и расскажет о паттерне, который можно встретить в любой игре, в том числе и настольной - Состояние. Этот шаблон занимает в игровой индустрии одну из самых заметных ролей, он очень популярен применительно к таким аспектам игры как искусственный интеллект - состояние определяет выполняемое действие, анимация - отображаем анимацию прыжка или бега, интерфейсы - переходы между окнами, или даже системы диалогов(привет картинка с Ведьмаком!). Если присмотреться, то игры практически полностью представляют из себя контролируемые последовательности, а следовательно, могут быть описаны с точки зрения этого паттерна.
Паттерны очень популярная тема в программировании, так что за теоретической информацией можно обратиться к этой замечательной книге или вот этой статье.
С практической точки зрения, в отличие от синглетона, который имеет довольно типичную реализацию почти во всех языках, состояния могут иметь довольно разнообразный вид. В зависимости от цели он может быть очень большим, для описания состояния в рамках какого-нибудь эвента, а может иметь вид простого switch
, для добавления поля с именем кота в UI. Поэтому приводить реализацию, которую можно было бы скопировать, не имеет смысла. За обычными примерами можно обратиться к приведённым выше статьям с теорией или поискать в интернете.
Ну раз с теорией и практикой покончено, перейдём к развлекательной части.
В современных игровых движках больша́я часть усилий брошена на создание инструментов доступных для всех желающих, не сильно знакомых с программированием. В Unity одной из таких вещей является механизм под названием - "Mecanim". Основная его цель - это создание анимаций, построенных, как вы догадываетесь, на основании машин состояний. Давайте посмотрим, сможем ли мы применить этот механизм, для реализации задач в общем виде.
Для примера сделаем простую сцену, которая по клику мышки будет переключаться между состояниями "Active"
и "Paused"
.
Создайте сцену и разместить на ней UI элемент с текстом
Создайте ассет AnimatorController
- это объект шаблон для нашей машины состояний
На вкладке "Animator"
(можно открыть по двойному клику на нашем новом ассете или через Window > Animation > Animator
) создайте два состояния "Active"
и "Paused"
Кликнув по стейту, можно добавить переход. Соедините стейты в обоих направлениях
Переключитесь на панель "Parameters"
и создайте триггер "Switch State"
Выделите переход между "Active"
и "Paused"
, в инспекторе выключите параметр "Has Exit Time"
, поставьте значение "Transition Duration"
в ноль, добавьте "Conditions” - “Switch State"
. То же самое проделайте с переходом из "Paused"
в "Active"
Создайте скрипт "Game"
|
|
Создайте скрипт "PauseState"
|
|
Создайте на сцене пустой объект и добавьте в него скрипт "Game"
, выставите текст, который будет отображать текущее состояние, а также добавьте компонент "Animator"
и выставьте в поле "Controller"
созданный на шаге 1 AnimatorController
Откройте закладку "Animator"
, выберите состояние "Paused"
и добавьте в него скрипт "PauseState"
В результате всех этих действий мы получим сцену, в которой состояние переключается по левому клику мышки, "Active"
проверяется из кода объекта напрямую, а состояние "Paused"
выполняет код непосредственно из машины состояний.
Данный метод похож на предложение почесать правое ухо левой ногой, но, с другой стороны, это реальный и проверенный механизм для создания машин состояний, хоть и предназначенный изначально для работы с анимациями. Не очень понятно почему разработчики не отделят функционал машины состояний от анимаций, превратив его в универсальный инструмент. Одно можно сказать точно - это один из основных инструментов при разработке игры на Unity, так что мы убили двух зайцев сразу и потренировались с Mecanim и вспомнили что такое паттерн Состояние. Хотя, вылавливая очередной баг в собственной реализации, этот способ может показаться не такой уж плохой альтернативой. Пока! =)