Как подключить конечный автомат к компонентной архитектуре? [закрыто]


23

Кажется, что конечные автоматы вызывают вредные зависимости в компонентных архитектурах.

Как, в частности, осуществляется связь между конечным автоматом и компонентами, которые выполняют поведение, связанное с состоянием?

Где я нахожусь:

  • Я новичок в компонентных архитектурах.
  • Я делаю файтинг, хотя не думаю, что это должно иметь значение. Я предполагаю, что мой конечный автомат используется для переключения состояний, таких как «заискивание», «лишение», «блокирование» и т. Д.
  • Я нашел эту технику управления состоянием самой естественной системой для архитектуры на основе компонентов, но она противоречит методам, о которых я читал: Система компонентов динамических игровых объектов для изменяемых символов поведения. Предполагается, что все компоненты активируют / деактивируют сами, постоянно проверяя условия для активации.
  • Я думаю, что такие действия, как «бег» или «ходьба», имеют смысл как состояния, что противоречит принятому здесь ответу: /gamedev//a/7934.
  • Я нашел это полезным, но неоднозначным: как реализовать поведение в компонентной игровой архитектуре? Он предлагает иметь отдельный компонент, который не содержит ничего, кроме конечного автомата. Но это требует некоторой связи между компонентом конечного автомата и почти всеми другими компонентами. Я не понимаю, как эта связь должна быть обработана. Вот некоторые догадки:

    О. Компоненты зависят от конечного автомата:
    Компоненты получают ссылку на компонент конечного автомата getState(), которая возвращает константу перечисления. Компоненты регулярно обновляются и проверяют это по мере необходимости.

    B. Конечный автомат зависит от компонентов.
    Компонент конечного автомата получает ссылки на все компоненты, которые он отслеживает. Он запрашивает их getState()методы, чтобы увидеть, где они находятся.

    C. Какая-то абстракция между ними.
    Используйте концентратор событий? Шаблон команды?

    D. Отдельные объекты состояния, которые ссылаются на компоненты
    State Pattern. Создаются отдельные объекты состояния, которые активируют / деактивируют набор компонентов. Конечный автомат переключается между объектами состояния.

  • Я смотрю на компоненты как на реализацию аспектов . Они делают все, что нужно внутренне, чтобы это произошло. Кажется, что компоненты должны функционировать самостоятельно, не полагаясь на другие компоненты. Я знаю, что некоторые зависимости необходимы, но конечные автоматы, похоже, хотят контролировать все мои компоненты.

Ответы:


7

Обзор довольно легкий, но посмотрите на эти слайды из презентации, которую я сделал для New Game Conf в прошлом году:

https://docs.google.com/presentation/d/110MxOqut_y7KOW1pNwIdcccisIA3ooJwVR-xm-ecuc4/view

(см. соответствующие изображения ниже)

Суть этого метода состоит в том, чтобы объединить шаблон списка действий (который объясняется - довольно плохо - на слайдах) с поведенческими автоматами, которые воздействуют на игровую сущность на основе компонентов.

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

Моей любимой частью этой конкретной игры было то, как мы могли создавать совершенно новых типов врагов, просто выбирая их из списка заранее написанных действий, помещая их в список действий для игрового объекта (находящегося в BrainComponent) в порядке желаемого приоритет, и все просто работает. Со списком действий, который позволяет блокировать / неблокировать действия, это может делать действительно крутые вещи, несмотря на то, насколько просто все это реализовать.

Даже поведение, такое как "оглушение", когда на самом деле просто StunBehaviorAction помещается в верхнюю часть стека списка действий; если поведение оглушения становится активным (после наблюдения, что EarsComponent игрового объекта услышал ошеломляющую ударную волну), тогда он устанавливает свое внутреннее состояние на Stunned, велит AnimationComponent воспроизводить анимацию оглушения и устанавливает состояние своего действия на Blocking, а таймер - на тайм-аут ожидания, извлеченный из EnemyParametersComponent игрового объекта. Поскольку это была Блокировка и она находилась в верхней части списка действий, ни один из других BehaviorAction в списке действий не вызвал бы свой метод обновления, поэтому они по сути были бы отключены. Когда время ожидания истекло, StunBehaviorAction вернул свое состояние в состояние ожидания, а в качестве состояния действия - NonBlocking.

Другие виды поведения, которые мы реализовали, были почти все реализованы с помощью одного внутреннего конечного автомата. На самом деле единственными двумя, у которых не было конечных автоматов, были PatrolPathBehaviorAction (он бы помещал серию PathAction в список действий, если бы он простаивал, что, в свою очередь, выдвигало MoveAction), и GuardHomeBehaviorAction (всегда в нижней части список действий, и всегда будет просто подтолкнуть PathAction обратно к месту расположения врага). Любое другое поведение было государственной машиной.

Слайд 10 Слайд 25 Слайд 26


В чем принципиальная разница между «поведением» и «действиями»?
щенок

1
@Pup: с точки зрения кода, как я его построил, поведение - это действие. С концептуальной точки зрения Действия обычно являются временными - они существуют только до тех пор, пока «не завершены», а Поведения вечны и никогда не удаляются из списка. Я видел, как другая команда создала подобную систему, но с двумя списками, один для действий и один для поведения, который работает достаточно хорошо. Мне нравится, когда у Action есть возможность блокировать определенное поведение, используя битовые маски и группирование (я думаю, что дорожки я назвал их на слайдах). Извините, графика среднего слайда настолько плохая. :)
Шон Миддледич

3

В предыдущей компании, в которой я работал, у нас была система на основе компонентов с ИИ на основе состояния. У нас был компонент ИИ, который контролировал все поведение этого объекта / подразделения. Когда ИИ был активен, например, блуждал, атаковал и т. Д., Он получал обновление каждого кадра, чтобы выполнить любую логику, которая была необходима. Когда ИИ работал на холостом ходу или не двигался, компонент был деактивирован и не обновлялся каждый кадр. Компонент, хотя и деактивированный, все же может получать сообщения на основе событий, поэтому он получит сообщение для чего-то вроде игрока, входящего в его агро-радиус, и может ответить на это, повторно активировав компонент AI, чтобы он мог выполнять обновления на основе фреймов.

Компонент AI имеет подкомпоненты, которые он может создавать и уничтожать на лету, в зависимости от того, какие действия он выполняет. Например, если он блуждает, он может создать блуждающий подкомпонент и обновлять каждый кадр во время блуждания, а затем, если aggro'd во время блуждания, он закроет этот подкомпонент и откроет подкомпонент атаки. Компонент AI должен быть независимым от всех других компонентов объекта. Например, у нас был компонент ввода, который бы просто запрашивал значения движения на единицу. Запрос, который он сделал, был чем-то, что отвечало бы и людям, и объектам ИИ. Это позволило компоненту ИИ просто устанавливать для себя значения движения во время таких вещей, как блуждание, на которое может подхватить компонент ввода, точно так же, как управляемый человеком компонент установит значения, на которые может поднять компонент ввода.


Итак, подкомпоненты ИИ на самом деле делают работу? Существовали ли они как компоненты сущности на том же уровне, что и компонент AI?
щенок

Подкомпоненты в нашем движке были частью базового класса компонентов. Таким образом, любой Component, полученный из BaseComponent, может иметь любое число SubComponents. Update()Метод BaseComponentбудет проверить список вспомогательных компонентов, и вызвать Update()на них. Subcomponentsбыли полностью необязательны, поэтому BaseComponentне могли иметь. Кроме того, любые сообщения, которые отправлялись в компонент, также направлялись субкомпонентам.
Ник Фостер

1

Немного неясно, что вы подразумеваете под компонентами, поскольку ваши термины очень расплывчаты без конкретных примеров. Часто игровые объекты строятся с использованием композиции, а не наследования. Таким образом, вы можете превратить их во что-то, что может нанести урон, добавив компонент здоровья к сущности, или вы можете сделать их одушевленными, добавив компонент одушевления. Можно также поместить ИИ в такой компонент. В вашем компоненте ИИ будет логика принятия решений, и если вы хотите связать это с большей частью другого кода в системе, вы можете собрать информацию на доске, к которой логике ИИ разрешен только доступ. Существует также проблема зависимостей на выходе системы ИИ. По сути, ваш ИИ контролирует сущность, и для этого контроля необходим интерфейс. Одна полезная концепция - это контроллер или геймпад. Ваш ИИ может заполнить аналогичную структуру, которую заполнит геймпад игрока (хотя он может иметь несколько дополнительных «кнопок» для определенных способностей). Теперь эта структура может быть передана вашему компоненту анимации, который будет интерпретировать ее и выбирать соответствующие анимации для воспроизведения. Разные подкомпоненты AI могут даже записывать в разные поля структуры или в одни и те же поля с разными приоритетами. Прицеливаться и ходить, например. Разные подкомпоненты AI могут даже записывать в разные поля структуры или в одни и те же поля с разными приоритетами. Прицеливаться и ходить, например. Разные подкомпоненты AI могут даже записывать в разные поля структуры или в одни и те же поля с разными приоритетами. Прицеливаться и ходить, например.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.