Управляемые данными состояния анимации

14

РЕДАКТИРОВАТЬ: Чтобы уточнить, что именно мой вопрос: это хороший способ обрабатывать анимацию / состояние анимации в игровом движке с прицелом на создание / управление контентом? Каковы недостатки в том, чтобы делать это таким образом, и какой альтернативный способ сделать это? - Хотя на мой ответ частично ответили в комментариях, похоже, это путь.

Я пытаюсь работать с анимацией в проекте, посвященном движку 2D-игр , без жесткого программирования. Жесткое кодирование состояний анимации кажется мне обычным, но очень странным явлением.

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

С состояниями анимации я имею в виду: "ходьба_лева", "ходьба_лева", "ходьба_право", "стрельба", ...

Моя идея обработки анимации состояла в том, чтобы спроектировать ее как модель, управляемую данными . Данные могут храниться в XML-файле, rdbms, ... и могут быть загружены в начале игры / уровня / ... Таким образом, вы можете легко редактировать анимацию и переходы, не изменяя код повсюду в вашем файле. игра.

В качестве примера я сделал черновой набросок определений данных, которые я имел в виду.

Одним из очень важных данных будет просто описание анимации . Анимация будет иметь уникальный идентификатор (описательное имя). Он будет содержать ссылочный идентификатор изображения (используемый им спрайт-лист, потому что разные анимации могут использовать разные спрайт-листы). Кадры в секунду для запуска анимации. Здесь «повтор» определяет, должна ли анимация запускаться один раз или бесконечно. Затем я определил список прямоугольников как фреймы.

<animation id='WIZARD_WALK_LEFT'>
    <image id='WIZARD_WALKING' />
    <fps>50</fps>
    <replay>true</replay>
    <frames>
        <rectangle>
            <x>0</x>
            <y>0</y>
            <width>45</width>
            <height>45</height>
        </rectangle>
        <rectangle>
            <x>45</x>
            <y>0</y>
            <width>45</width>
            <height>45</height>
        </rectangle>
    </frames>
</animation>

Данные анимации будут загружаться и храниться в пуле ресурсов анимации, и на них будут ссылаться игровые объекты, которые их используют. Это будет рассматриваться как ресурс, как изображение, звук, текстура, ...

Вторым элементом данных, который нужно определить, будет конечный автомат для обработки состояний анимации и переходов. Это определяет каждое состояние, в котором может находиться игровой объект, в какие состояния он может перейти и что вызывает изменение этого состояния.

Этот конечный автомат будет отличаться от объекта к объекту. Потому что у птицы могут быть состояния «ходьба» и «полет», в то время как у человека будет только состояние «ходьба». Однако он может быть разделен между различными объектами, потому что несколько людей, вероятно, будут иметь одинаковые состояния (особенно когда вы определяете некоторых общих NPC, таких как монстры и т. Д.). Кроме того, у орка могут быть те же состояния, что и у человека. Просто чтобы продемонстрировать, что это определение состояния может быть общим, но только для выбранной группы игровых объектов .

<state id='IDLE'>
  <event trigger='LEFT_DOWN' goto='MOVING_LEFT' />
  <event trigger='RIGHT_DOWN' goto='MOVING_RIGHT' />
</state>
<state id='MOVING_LEFT'>
  <event trigger='LEFT_UP' goto='IDLE' />
  <event trigger='RIGHT_DOWN' goto='MOVING_RIGHT' />
</state>
<state id='MOVING_RIGHT'>
  <event trigger='RIGHT_UP' goto='IDLE' />
  <event trigger='LEFT_DOWN' goto='MOVING_LEFT' />
</state>

Эти состояния могут обрабатываться системой опроса . Каждый тик игры захватывает текущее состояние игрового объекта и проверяет все триггеры. Если условие выполнено, оно меняет состояние объекта на состояние «Перейти».

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

Вот пример XML, как я бы определил поведение анимации и графическое представление некоторых общих сущностей в игре, обращаясь к состоянию анимации и идентификатору данных анимации. Обратите внимание, что и "wizard", и "orc" имеют одинаковые состояния анимации, но разные анимации. Кроме того, другая анимация может означать другой лист спрайта или даже другую последовательность анимаций (анимация может быть длиннее или короче).

<entity name="wizard">
    <state id="IDLE" animation="WIZARD_IDLE" />
    <state id="MOVING_LEFT" animation="WIZARD_WALK_LEFT" />
</entity>

<entity name="orc">
    <state id="IDLE" animation="ORC_IDLE" />
    <state id="MOVING_LEFT" animation="ORC_WALK_LEFT" />
</entity>

Когда объект создается, он добавляет список состояний с данными конечного автомата и ссылкой на данные анимации.

В будущем я бы использовал систему сущностей для создания целых сущностей, определяя компоненты в аналогичном формате xml.

-

Это то, что я придумал после некоторых исследований. Однако у меня возникли некоторые проблемы, и я надеялся получить обратную связь. Есть ли здесь что-то, что не имеет смысла, или есть лучший способ справиться с этими вещами? Я понял идею итерации по кадрам, но у меня возникли проблемы, чтобы сделать шаг вперед, и это моя попытка сделать это.

user8363
источник
1
Я придумал аналогичную идею для хранения данных анимации, хотя я не рассматривал триггеры. Вот небольшая статья, которую я написал об этом, и ссылка на проект XNA, который я написал, который использует XML и обрабатывает аспекты анимации. У меня есть несколько вещей, которые отличаются, например, концепция множеств и последовательностей, но кроме этого, я думаю, вы на правильном пути.
Джон Макдональд
2
Не то, чтобы ваш дизайн был плохим (это не так, он очень похож на аналогичную систему, которую я построил в прошлые времена), но какой именно ваш вопрос здесь? Я думаю, что это действительно может быть яснее.
MrCranky
@ Джон - Спасибо, приятель, я посмотрю на это позже этим вечером. @ MrCranky - Ну, в основном то, что ты сказал. Если это хорошо и, возможно, советы / ссылки на более устоявшиеся методы. Я действительно в темноте здесь, по опыту.
user8363
1
Я хотел бы выразить это за глубину предоставленной информации, но, повторяя мистера Крэнки, я не совсем понимаю, в чем заключается вопрос. Для моего личного совета (который породил создание такой системы пару недель назад), я бы сказал, что вы на месте.
Майк Клак
@MikeC Это просто ответ, который мне нужен. Я извиняюсь за то, что не смог прояснить свой вопрос. Может быть, если бы меня не заметили, это было бы больше похоже на вопрос :). Дело в том, что я не смог найти много ресурсов, которые касались состояний анимации и тех, которые жестко закодировали ее, поэтому создание / изменение контента было бы кошмаром. Итак, мой вопрос: этот подход правильный или нет? И если вы, ребята, говорите, что это так, то это нормально :).
user8363

Ответы:

4

Анимационные клипы лучше всего описывать в виде простых старых данных, как вы это делали в своем первом фрагменте XML. Вы можете сделать это вручную или экспортировать в него из художественной упаковки. В любом случае, вы, вероятно, захотите создать конвейер, который берет его из понятного человеку промежуточного формата, такого как XML, и помещает его во что-то приятное и быстрое для загрузки.

Следующим шагом будет возможность сделать вещь. Если вы используете какой-то граф сцены, это, вероятно, будет означать создание Anim Node для него. Вы должны быть в состоянии сказать узлу anim, какую анимацию он воспроизводит в данный момент, и где на временной шкале он находится в данный момент. Убедитесь, что вы сохраняете доступ к информации ограничительного ящика на этом уровне, чтобы ее можно было легко вставить в систему отбора.

Теперь вы захотите связать анимацию с игровой сущностью. Я склонен использовать компонентную модель, поэтому для меня это означает и компонент AnimState. Это ваш промежуточный слой между геймплеем и рендерингом. Он отслеживает, какую анимацию воспроизводит объект, режимы воспроизведения (зацикливание, однократный, пинг-понг и т. Д.), Время и т. Д. Он может отправлять события, такие как «animover», обратно к объекту и обновляет состояние анимоделя, когда это необходимо. , AnimStates для активных объектов будет обновляться один раз за сим, если они воспроизводят анимацию.

Компонента animstate, вероятно, достаточно для простых игровых элементов (базовые фоновые реквизиты и т. П.), Но для более сложных объектов вы захотите использовать конечный автомат для управления им. Это лучше всего выражается на языке сценариев, таких как Lua или Python. Состояние может иметь несколько функциональных блоков (onEnter, onExit, onUpdate, onEvent), а также временную шкалу, которая определяет определенные действия и триггеры, которые должны происходить в определенное время. Вероятно, у вас будет какой-то класс менеджера, который отвечает за обновление этих конечных автоматов соответствующим образом, а также за запуск обратных вызовов временной шкалы при их возникновении. Вы должны стараться сохранять эти события как можно более основанными на событиях, так как каждое написанное вами OnUpdate будет стоить линейно с учетом количества объектов. Вы также захотите указать теги («атакующий», «холостой», «ignoreinput» и т. д.), которые связаны как с целыми состояниями, так и с определенными временными областями состояний. Возможно, вам также понадобятся высокоуровневые обработчики событий, которые применяются ко всему графу состояний, а не только к определенному состоянию.

У «чувствительных» персонажей, вероятно, также будет какой-то ИИ. Я склонен делать определенный «локомоторный» компонент, который справляется с ходьбой. Он взаимодействует с графом состояний, используя систему сигналов и событий и запрашивая теги состояний, и ему можно сказать «идти до точки» или «бежать в определенном направлении с определенной скоростью». Компоненты AI более высокого уровня (например, дерево поведения или что-то еще) могут затем использовать этот интерфейс, не беспокоясь о деталях.

Kevin
источник
1

Лучшая система анимации, управляемая данными, которую я когда-либо видел, это Blend Tree . На самом деле, это чертовски хорошо, и он может сделать все, что вы просите здесь. Согласно AIGameDev.com, теперь это де-факто стандарт в отрасли, и я считаю, что они правы.

К сожалению, я не нашел хорошего ресурса с быстрым поиском, но вы можете попробовать то или иное , чтобы получить обзор. На AIGameDev.com есть также платная статья , не знаю, стоит ли приобретать премиум-аккаунт.

Лоран Кувиду
источник
Это очень хороший ресурс, спасибо. Я ищу такую ​​информацию.
user8363
1
Смешивание анимации невозможно с дискретными спрайт-листами, только с непрерывной скелетной анимацией
AlexFoxGill