Keep your place in this quest

Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.

По мере развития вашего геймплея вам потребуется создавать объекты, которые ведут себя по-разному в зависимости от текущего состояния. Враг может находиться в режиме ожидания, патрулировать, преследовать, атаковать, быть оглушённым или мертвым. Дверь может быть закрыта, открываться, открыта или заблокирована. Бой с боссом может проходить через несколько фаз.

Именно здесь становятся полезны машины состояний.

image.png

На изображении выше показан стандартный враг, создаваемый Crave для нового проекта, с открытой справа машиной состояний. Мы находимся внутри состояния «wander», которое содержит внутренние состояния, такие как «random selector» (начальное состояние, обозначенное зеленым цветом), «go to random» и «idle». Видны переходы между состояниями, обозначенные стрелками, и то, что каждое состояние может иметь свою логику — либо на Python, как показано на изображении, либо через logic bricks.

Машина состояний помогает организовать поведение в чёткие состояния вместо того, чтобы писать один большой скрипт с множеством несвязанных условий.

В этом уроке вы узнаете:

  • Что такое состояние.
  • Что такое переход.
  • Почему иерархические машины состояний полезны.
  • Как компонент State Machine встроен в сущность.
  • Как работают On Enter, On Update и On Exit.
  • Как Python и Logic Bricks могут использоваться внутри состояний и переходов.

Цель — сначала понять ментальную модель. Как только она станет понятной, использование редактора станет значительно проще.

Что такое состояние?

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

image.png

Например, у врага могут быть такие состояния:

  • Idle
  • Patrol
  • Chase
  • Attack
  • Dead

Обычно в данный момент времени враг может находиться только в одном состоянии. Если враг в Patrol, он не должен одновременно выполнять поведение атаки. Если он в Dead, он не должен продолжать преследовать игрока.

Это упрощает понимание геймплея, поскольку у каждого состояния есть чёткая задача.

Состояние Что оно может делать
Idle Стоять на месте и ждать.
Patrol Перемещаться между точками.
Chase Двигаться к игроку.
Attack Выполнять анимацию атаки и наносить урон.
Dead Отключать движение и проигрывать анимацию смерти.

Вместо того чтобы спрашивать у одного огромного скрипта «что враг должен делать в этом кадре?», вы спрашиваете «в каком состоянии сейчас враг?»

Что такое переход?

Переход — это правило, которое переводит машину состояний из одного состояния в другое.

image.png

Например:

  • из Idle в Patrol, когда враг должен начать движение, по таймеру.
  • из Patrol в Chase, когда игрок обнаружен.
  • из Chase в Attack, когда враг достаточно близко.
  • из Attack в Chase, когда атака закончилась.
  • из любого состояния в Dead, когда здоровье достигает нуля.

Переход — не поведение, а решение «теперь нужно сменить состояние».

Это разделение важно. Состояние Attack фокусируется на атаке, а переход решает, когда войти или выйти из этого состояния.

Почему иерархические машины состояний полезны

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

Например, врага можно организовать так:

Alive
    Idle
    Patrol
    Chase
    Attack
Dead

Состояния Idle, Patrol, Chase и Attack принадлежат более широкому состоянию Alive. Это упрощает структуру и помогает избежать повторения одной и той же логики в нескольких местах.

Для начинающего проекта можно начать с простой плоской машины состояний. Но по мере усложнения геймплея иерархия помогает поддерживать логику в чистоте.

Компонент State Machine

Чтобы использовать машину состояний в сцене, сущность должна иметь компонент State Machine.

Компонент связывает сущность с машиной состояний (State Machine) как объектом. Объект определяет состояния, переходы и логику, а компонент запускает эту логику на сущности во время игры.

Это похоже на другие системы Cave:

Объект Компонент
Python Script Python Component запускает его.
Animation Animation Component проигрывает её.
State Machine State Machine Component запускает её.

На практике это значит, что у вашей сущности врага может быть компонент State Machine, который запускает AI-анимацию врага.

Объект машины состояний может иметь свойства — это видно на вкладке свойств, и эти свойства можно локально менять в компоненте машины состояний, что позволяет создавать модульные машины состояний с разными настройками для разных типов сущностей.

События состояния

Каждое состояние может реагировать на три важных момента:

Событие Когда происходит Обычно используется для
On Enter При начале состояния. Сброс таймеров, инициализация переменных, запуск анимации, выбор цели.
On Update Пока состояние активно. Движение, проверка расстояний, обновление таймеров.
On Exit При выходе из состояния. Остановка эффектов, очистка временных значений.

Например, состояние Attack может работать так:

  • On Enter: проиграть анимацию атаки.
  • On Update: дождаться момента удара или callback анимации.
  • On Exit: сбросить флаг атаки.

Это делает каждое состояние небольшим самостоятельным поведением.

Python внутри состояний

Машины состояний могут использовать Python для логики.

В Python-коде каждого состояния Cave предоставляет полезные переменные, такие как entity и scene, поэтому состояние может управлять сущностью, которой принадлежит компонент State Machine.

Например, состояние может воспроизвести звук при входе:

cave.playSound("Enemy Alert", volume=0.8)

Или прочитать свойство у сущности:

health = entity.properties.get("health", 100)

Так логика состояния остаётся тесно связанной с поведением.

Python внутри переходов

Переходы тоже могут использовать Python. Для Python-логики перехода в Cave используется переменная result. Если result становиться True, то переход происходит. Например, переход в состояние Dead может проверять здоровье так:

health = entity.properties.get("health", 100)
result = health <= 0

Переход из Chase в Attack может проверять расстояние, если ваш скрипт или свойства сущности предоставляют эту величину:

player = scene.get("Player")
playerPos = player.getTransform().getWorldPosition()
entityPos = entity.getTransform().getWorldPosition()

distanceToPlayer = (playerPos - entityPos).length()
result = distanceToPlayer < 2.0

Конкретные данные зависят от вашей игры, но идея всегда одна — переход решает, когда пора менять состояние.

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

Logic Bricks внутри машин состояний

Машины состояний могут также использовать Logic Bricks.

Это полезно, когда вы хотите создавать поведение визуально, вместо написания кода на Python. Для многих игровых задач Logic Bricks — очень доступный способ связать события, условия и действия.

Они работают точно так же, как описано выше для Python-кода внутри состояния или перехода. Logic Bricks состояния и перехода уже инициализированы нужными кирпичиками, чтобы начать работу.

Вы можете комбинировать Python и Logic Bricks в зависимости от того, что яснее для поведения, которое создаёте. Если у состояния или перехода используются оба, то выполняются оба, и переход происходит, если выполнено хотя бы одно условие.

Когда использовать машину состояний

Используйте машину состояний, когда у объекта есть чёткие режимы поведения.

Хорошие примеры:

  • AI врага.
  • Фазы босса.
  • Двери и взаимодействующие объекты.
  • Логика миссий и квестов.
  • Прогресс катсцен.
  • Состояния способностей персонажа.

Машина состояний может быть не нужна для простых одноразовых объектов. Если, например, подбор предмета лишь воспроизводит звук и исчезает, достаточно небольшого скрипта на Python или набора Logic Bricks.

Что нужно запомнить

Машина состояний организует геймплей в состояния и переходы.

Состояния описывают текущее действие. Переходы решают, когда переключиться на другое. On Enter, On Update и On Exit помогают сохранять каждое состояние сфокусированным и читаемым.

Для простого поведения достаточно скрипта. Для поведения с несколькими режимами машина состояний обычно облегчает понимание и расширение логики.