Система Anim: конечный автомат, граф состояний

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

Конечный автомат и граф состояний

Конечный автомат (Finite State Machine, FSM) — это модель вычислений, которая состоит из ограниченного набора состояний и переходов между ними. Каждый переход в графе состояний ассоциируется с определённым событием или условием. В контексте анимации, состояния — это различные анимационные фазы объекта (например, idle, run, jump и т.д.), а переходы — это логика, определяющая, когда анимация должна измениться или завершиться.

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

Основные элементы системы Anim

  1. AnimComponent Компонент anim в PlayCanvas отвечает за управление анимациями объекта. Он содержит методы и свойства для проигрывания, остановки и перехода между анимациями. Внутри компонента хранятся все анимации, которые могут быть привязаны к объекту, а также управление их состоянием.

  2. State Graph Это основной механизм, который управляет анимациями через граф состояний. Каждый узел графа представляет собой отдельную анимацию или группу анимаций, а рёбра — это условия или триггеры для перехода между этими состояниями. Это позволяет создать сложные анимационные переходы в зависимости от разных событий или состояний игры.

  3. Transitions Переходы между состояниями (анимациями) являются неотъемлемой частью графа состояний. Каждый переход может быть настроен с условиями, такими как время, флаги состояния или внешние события. Эти условия проверяются при каждом обновлении, и если они выполняются, происходит переход в новое состояние.

Создание графа состояний

Для создания графа состояний в PlayCanvas используется объект AnimStateGraph. Граф состоит из множества состояний, каждое из которых может содержать несколько анимационных клипов. Состояния могут быть связаны переходами, которые, в свою очередь, могут быть настроены через различные параметры.

var stateGraph = new pc.GraphNode();
var idleState = stateGraph.addChild(new pc.GraphNode('Idle'));
var runState = stateGraph.addChild(new pc.GraphNode('Run'));

idleState.addComponent('animation', {
    assets: [idleAnimAsset]
});

runState.addComponent('animation', {
    assets: [runAnimAsset]
});

var transition = idleState.addChild(new pc.GraphNode('TransitionToRun'));
transition.addComponent('transition', {
    from: idleState,
    to: runState,
    condition: 'playerRunning'
});

В данном примере создаются два состояния: Idle и Run. Состояние Idle проигрывает анимацию отдыха, а состояние Run — анимацию бега. Между этими состояниями добавляется переход, который активируется, если выполняется условие playerRunning.

Параметры переходов

Переходы между состояниями можно настроить с использованием различных параметров:

  1. Условие (Condition) Условие — это логика, которая проверяется перед выполнением перехода. Условия могут быть различными: например, это может быть проверка перемещения персонажа, изменения его состояния или даже время.

  2. Скорость (Speed) Каждый переход может быть настроен на определённую скорость анимации. Это полезно для создания плавных переходов, например, из состояния бега в состояние прыжка.

  3. Задержка (Delay) Задержка перед выполнением перехода может быть настроена для более сложных анимационных эффектов. Задержки могут быть полезны для создания эффекта “выдержки” перед сменой анимации.

var transition = idleState.addChild(new pc.GraphNode('TransitionToRun'));
transition.addComponent('transition', {
    from: idleState,
    to: runState,
    condition: 'playerRunning',
    speed: 0.5,
    delay: 0.2
});

Пример работы с анимациями через FSM

Для того чтобы задействовать систему конечных автоматов в PlayCanvas, необходимо правильно настраивать события, которые будут отслеживаться и вызывать переходы. Рассмотрим пример простого FSM для персонажа, который должен переключаться между состояниями “Стояние”, “Бег” и “Прыжок”.

  1. Сначала создаём состояние “Idle”, которое проигрывает анимацию стояния.
  2. Переход из “Idle” в “Run” активируется при движении персонажа (например, нажатие клавиши).
  3. Переход из “Run” в “Jump” происходит, когда персонаж прыгает.
var stateGraph = new pc.GraphNode();

var idleState = stateGraph.addChild(new pc.GraphNode('Idle'));
var runState = stateGraph.addChild(new pc.GraphNode('Run'));
var jumpState = stateGraph.addChild(new pc.GraphNode('Jump'));

idleState.addComponent('animation', {
    assets: [idleAnimAsset]
});

runState.addComponent('animation', {
    assets: [runAnimAsset]
});

jumpState.addComponent('animation', {
    assets: [jumpAnimAsset]
});

var idleToRun = idleState.addChild(new pc.GraphNode('IdleToRun'));
idleToRun.addComponent('transition', {
    from: idleState,
    to: runState,
    condition: 'isRunning'
});

var runToJump = runState.addChild(new pc.GraphNode('RunToJump'));
runToJump.addComponent('transition', {
    from: runState,
    to: jumpState,
    condition: 'isJumping'
});

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

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

Одним из ключевых аспектов работы с системой анимации в PlayCanvas является управление состоянием анимации. На каждом кадре игры система проверяет текущее состояние объекта и соответствующие условия для переходов. Когда переход выполняется, анимация объекта меняется, что влияет на визуальное поведение модели.

Для отслеживания текущего состояния анимации можно использовать методы компонента anim, такие как:

  • anim.currentState: возвращает текущее состояние анимации.
  • anim.play(name): запускает анимацию с указанным именем.
  • anim.stop(): останавливает текущую анимацию.
if (anim.currentState === 'Idle' && player.isRunning) {
    anim.play('Run');
}

if (player.isJumping && anim.currentState !== 'Jump') {
    anim.play('Jump');
}

Заключение

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