Unity Gems: Advanced Tutorial on Finite State Machines

Our new tutorial on Finite State Machines goes far beyond the simple switch statement. Provided in multiple parts this tutorial builds to create a powerful and fast delegate driven Finite State Machine framework.

Already 2 parts are published:

Part 1 covers an introduction to code based FSMs and shows how to re-engineer a project to be more stable and robust by using simple FSM techniques.

Part 2 starts the process of building an advanced delegate driven, reflection powered FSM framework with a detailed look at how to maximise performance by using delegates and how anonymous functions and closures can be used to create some really powerful, easy to understand code.

If you want to know more about advanced language features of C# and how they can be used to maximise the performance or your game and the legibility of your code then this community written tutorial will be a great starting point. In coming parts we will be covering the inner workings of coroutines in detail.


Also check out our Memory Management tutorial that covers the basics of object pooling, stucts vs classes and garbage collection. A really useful intro for people moving to C# from C or C++ backgrounds and interesting we hope for everyone else!

[mod edit: links removed, outdated]

Some excellent information here, maybe even too excellent!

I wonder if some people may find parts of this tutorial a bit complicated? I think some more diagrams would help, FSM’s are perhaps easier(?) to model visually.

For example, have you read Mat Buckland’s article on State Driven Agent Design? I found that quite approachable.

Good point - I believe I did read that article a while ago. I will add some more pictures!

Part 3 is published along with a fully playable online version of the game built in the tutorial.

This framework now supports callable states, wiring of .NET events and redirection of SendMessage.

Great tutorials! Thank you. It was little to much for me though as I was creating simple Game Manager for my puzzle game but followed your approach with State Machine and obviously used Singleton pattern to have just one instance of an object across all Scenes.
Here is quick example of the code.

Thank you very much!

Your site rocks. It’s one of the most useful sites I’ve stumbled upon.

Well, this is old, and UnityGems doesnt open anymore, but I did find a backup of the site somewhere. So I was able to follow along your tutorials. I’m hoping someone is here to still help. I agree with Brian there, that site is great, needs to be reopened :smile:
But anyway, Im on part 2 of the FSM tutorials. Followed along, writing my own code, until I came upon an error:

ArgumentException: method return type is incompatible
System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Delegate.cs:190)
System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Delegate.cs:276)
StateMachineBase.ConfigureDelegate[Func`1] (System.String methodRoot, System.Func`1 Default) (at Assets/Scripts/FSM/StateMachineBase.cs:220)
StateMachineBase.ConfigureCurrentState () (at Assets/Scripts/FSM/StateMachineBase.cs:196)
StateMachineBase.set_currentState (System.Enum value) (at Assets/Scripts/FSM/StateMachineBase.cs:43)
FighterFSM.Idle_Update () (at Assets/Scripts/FSM/FighterFSM.cs:62)
StateMachineBase.Update () (at Assets/Scripts/FSM/StateMachineBase.cs:72)

Ive ended up copying and pasting the code, and Im still getting this error. Seems CreateDelegate doesnt like the EnterState or ExitState, and those are the only 2 coroutines. So theres a problem with the IEnumerator. Cutting out all Enter and ExitStates, the code will run fine. And thats what Ill end up with if no one can help.

Heres the code snippets…

private void ConfigureCurrentState()
{
    ...
    Func<IEnumerator> enterState = ConfigureDelegate<Func<IEnumerator>>("EnterState", DoNothingCoroutine);
    ExitState = ConfigureDelegate<Func<IEnumerator>>("ExitState", DoNothingCoroutine);
    ...
}

T ConfigureDelegate<T>(string methodRoot, T Default) where T : class
{
    var mtd = GetType().GetMethod(_currentState.ToString() + "_" + methodRoot, System.Reflection.BindingFlags.Instance  | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod);

    if (mtd != null)               
        return Delegate.CreateDelegate(typeof(T), this, mtd) as T;
    else
        return Default;
}

If more than this is needed, Ill post the whole files, but I think its more in the system somewhere and Im not using CreateDelegate correctly for coroutines. Dont you hate it when the code changes and old tutorials dont work anymore?

Thanks in advance to whoever wants to help or point me off in the right direction.

Figures, just started changing it over to not use coroutines on Enter and ExitState, and I realized the problem. My Enter and Exits were returning void, not IEnumerator…Switched that on over and yields and such and it works now fine!
Problem solved!

Hi.

I want to see full code.

I am searching more neat code for state-driven architecture or turn-based game’s actual C# code.

Thx.

Hi all,

For anyone looking for the tutorials referenced in this thread, they can be found here:

This is the 2012 snapshot.

In case someone is still in need, I have redone the articles to my own.

And if you think something is missing or could be done better, please let me know.