Finite State Machines

Animancer includes a general purpose FSM system which is flexible enough for most needs, but it is not tied to the animation system in any way so you can use either one without the other if you want to.

The full source code of the Animancer.FSM system is included with both Animancer Lite and Pro (in the Assets/Plugins/Animancer/Utilities/FSM folder).

Basic Usage

Instructions More Information
1. Make a base state class which implements IState. State Types
2. Make a StateMachine<TState> field where TState is the class you just made. Initialization
3. Initialize that field with a new StateMachine(). Initialization
4. Change the current state by calling stateMachine.TrySetState(nextState). Changing States
5. Access the current state using its CurrentState property. Changing States

Here is a simple script which shows the system in action:

If you want to try it out:

  1. Copy the code below into a new C# script called StateMachineExample.cs (to match the StateMachineExample class name).
  2. Drag that script onto an object in the scene.
  3. Enter Play Mode.
  4. Observe the messages it logs in the Console window.
  5. Click the mouse to change states.
using Animancer.FSM;
using UnityEngine;

public sealed class StateMachineExample : MonoBehaviour
{
    private LoggerState _Idle = new LoggerState("Idle");
    private LoggerState _Walk = new LoggerState("Walk");
    
    private readonly StateMachine<LoggerState> StateMachine = new StateMachine<LoggerState>();

    private void Awake()
    {
        // Start in the Idle state.
        StateMachine.ForceSetState(_Idle);
    }

    private void Update()
    {
        // Swap between the two states whenever the mouse is clicked.
        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("Mouse was Clicked");
            
            if (_StateMachine.CurrentState == _Idle)
                _StateMachine.TrySetState(_Walk);
            else
                _StateMachine.TrySetState(_Idle);

            // Each of those TrySetState calls will check:
            // CanExitState on the previous state.
            // CanEnterState on the next state.

            // Then since they both return true it will change the state and call:
            // OnExitState on the previous state.
            // OnEnterState on the next state.

            // See the Changing States page for more details.
        }
    }
}

public sealed class LoggerState : IState
{
    public readonly string Name;

    public LoggerState(string name)
    {
        Name = name;
    }

    public bool CanEnterState
    {
        get
        {
            Debug.Log("CanEnterState: " + Name);
            return true;
        }
    }

    public bool CanExitState
    {
        get
        {
            Debug.Log("CanExitState: " + Name);
            return true;
        }
    }

    public void OnEnterState()
    {
        Debug.Log("OnEnterState: " + Name);
    }

    public void OnExitState()
    {
        Debug.Log("OnExitState: " + Name);
    }
}

The State Machines examples demonstrate how to use it in more detail and the 3D Game Kit example demonstrates how to completely redesign an Animator Controller based character to use this system instead (as well as solve some of the issues with the original implementation).

Overview A summary of the system structure and the reasons it was designed that way.
1. State Types Common base state types.
2. Initialization How to create and initialize state machines.
3. Changing States How to change the current state of a state machine.
Keys Keyless and keyed state machines.
Utilities Various other utilities that are included with the system.