Leaning about State Machines

I’ve been in programming for a couple of years but I’m new to game Dev. I started on GoDot but recently decided to give Unity a try as it’s what my friends are using.

One thing I’ve been struggling to get my head around (in both engines) but equally fascinated by and have an urge to master, is State Machines. Particularly when talking about player movement and actions.

Most courses seem to brush over this topic and try to handle movement as simply as possible. This is fine as it often covers things like idle, moving, climbing and jumping… but if I then want to make it so you can jump whilst climbing or double jump, i often have to change how things work quite a bit.

I feel like state machines should solve this issue and make the code tidier and easier to manage… I want to be at a point where I can add any state I can think of to my player without having to rewrite all the movement methods… but in not there yet.

Does anyone have any tips or can point me to some good up to date tutorials or courses that cover state machines in detail? It’s a subject I really want to master :grin:

State machines can be more performant and are easier to write but they often require much more code. There’s many ways to do them. You can add multiple scripts to a gameObject and only enable the scripts that are relevant to the current state. Or you can just use Invoke and InvokeRepeating but InvokeRepeating can be difficult to sync with Update and so some people choose to use coroutines instead.

In my last project I used a delegate from FixedUpdate to call the relevant state.

    public delegate void State();
    public State myState;

    void Start()
    {
        myState = Grounded;
    }

    void FixedUpdate()
    {
        myState();
    }

    void Grounded()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            rb.AddForce(Vector3.up * 100);
            myState = Flying;
        }
        // do other grounded stuff:
    }

    void Flying()
    {
        if (rb.velocity.y < 0.1f && Physics.SphereCast(transform.position, 0.5f, -transform.up, out RaycastHit hit, 0.6f))
            myState = Grounded;

        // do other flying stuff:
    }

The above is just a demonstration as I found a state machine wasn’t needed for my player code but very necessary for the AI code.

A state machine is a mathematical concept describing a system that transitions between various states based on specific inputs.

There are multiple ways to implement a state machine, including using if statements or switch cases with enums. However, the most widely accepted approach is the state pattern, as it allows for easier state addition, removal, debugging and testing.

You can read about it here: https://refactoring.guru/design-patterns/state and the C# implementation here: https://refactoring.guru/design-patterns/state/csharp/example

This is an old post, but the ideas (virtual controllers, layered FSMs) are still very relevant for full-featured character controllers: Best practices handling input, movement, animation with scripts?