Finite-state machine in Unity

Maybe some of you guys might be thinking: “Uh, just another dudes making an own finite-state machine… what for?“. Well, we asked ourselves the same question: “Why don’t we simply use someone else’s implementation?“. The Unity Finite State Machine Tutorialis pretty cool but we wanted to make a few things easier to maintain, or at least try to do so.

Our main goals were to:

make a machine out of templates that can be easily expanded, adjusted and altered

make parameters as accessible as possible from the Unity Editor

make a finite-state machine which is similar to the Animator FSM in Unity

This is why Till created an easiest version of a finite-state machine, he could think of, starting with only two states (idle and running) and only one transition (on key press).

The outcome:

The setup:

The StateMachine game object (GO) contains the StateManager.cs script. States can be added to this GO, simply as children GOs. Basically, the StateManager.cs script only activates the start state (set as public StartState) and deactivates all other states. Furthermore, all states (children) of the StateManager GO are saved to a private array during Awake() for further use.

The states:

Let’s take a closer look at the states, which can be added as children GO to the StateMachine GO. The StateIdle GO has two scripts: a StateIdle.cs script, which derives from the base class CState and a TransitionOnKeyPress.cs script, which derives from CTransition.

Each state game object in the machine is supposed to have exactly one state script, but can have multiple transition scripts. Only one state can be active at a time, means only the update function of the active state is called.

CState is a very simple base class. Maybe we will need some more lines in the future. So far, it just defines that:

each derived class needs to have a name

each derived class can do some extra stuff OnDrawGizmos

it draws the state name onto the screen using our own simple DrawText function for Gizmos

So far, the StateIdle.cs script doesn’t do that much. It just defines the state name and logs a debug statement, on enable. You could define the particular details of that state later on.

The transitions:

For the transitions, we have a base class CTransition which is similar to CState. It defines a public ToState, which has to be set in the Editor in all derived classes. Each derived transition needs to define a method, which checks if the transition should trigger. This check is called on every update.

The derived class from CTransition simply checks for the key press and triggers the transition. You can create other transition types by using TransitionOnKeyPress.cs as a template and modifying it to your needs.

And that’s it. The whole machine can be simply extended by adding new states (children GOs), states can be decorated with more contents and all kinds of transitions can be created and added to the different states. It’s totally up to you… Your feedbacks, thoughts and comments are welcome!