Search Unity

Unity Gems: Advanced Tutorial on Finite State Machines

Discussion in 'Made With Unity' started by whydoidoit, Nov 1, 2012.

  1. whydoidoit

    whydoidoit

    Joined:
    Mar 12, 2012
    Posts:
    365
    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]
     
    Last edited by a moderator: Jul 11, 2019
  2. CrazySi

    CrazySi

    Joined:
    Jun 23, 2011
    Posts:
    538
    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.
     
  3. whydoidoit

    whydoidoit

    Joined:
    Mar 12, 2012
    Posts:
    365
    Good point - I believe I did read that article a while ago. I will add some more pictures!
     
  4. whydoidoit

    whydoidoit

    Joined:
    Mar 12, 2012
    Posts:
    365
    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.

     
  5. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    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.
     
  6. GeneBox

    GeneBox

    Joined:
    Nov 15, 2012
    Posts:
    480
    Thank you very much!
     
  7. brianasu

    brianasu

    Joined:
    Mar 9, 2010
    Posts:
    369
    Your site rocks. It's one of the most useful sites I've stumbled upon.
     
  8. pjmavcom

    pjmavcom

    Joined:
    May 17, 2013
    Posts:
    2
    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 :D
    But anyway, Im on part 2 of the FSM tutorials. Followed along, writing my own code, until I came upon an error:

    Code (CSharp):
    1. ArgumentException: method return type is incompatible
    2. 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)
    3. 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)
    4. StateMachineBase.ConfigureDelegate[Func`1] (System.String methodRoot, System.Func`1 Default) (at Assets/Scripts/FSM/StateMachineBase.cs:220)
    5. StateMachineBase.ConfigureCurrentState () (at Assets/Scripts/FSM/StateMachineBase.cs:196)
    6. StateMachineBase.set_currentState (System.Enum value) (at Assets/Scripts/FSM/StateMachineBase.cs:43)
    7. FighterFSM.Idle_Update () (at Assets/Scripts/FSM/FighterFSM.cs:62)
    8. 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...

    Code (CSharp):
    1. private void ConfigureCurrentState()
    2. {
    3.     ...
    4.     Func<IEnumerator> enterState = ConfigureDelegate<Func<IEnumerator>>("EnterState", DoNothingCoroutine);
    5.     ExitState = ConfigureDelegate<Func<IEnumerator>>("ExitState", DoNothingCoroutine);
    6.     ...
    7. }
    8.  
    9. T ConfigureDelegate<T>(string methodRoot, T Default) where T : class
    10. {
    11.     var mtd = GetType().GetMethod(_currentState.ToString() + "_" + methodRoot, System.Reflection.BindingFlags.Instance  | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod);
    12.  
    13.     if (mtd != null)              
    14.         return Delegate.CreateDelegate(typeof(T), this, mtd) as T;
    15.     else
    16.         return Default;
    17. }
    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.
     
  9. pjmavcom

    pjmavcom

    Joined:
    May 17, 2013
    Posts:
    2
    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!
     
  10. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,476
    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.
     
  11. DustySkunk

    DustySkunk

    Joined:
    Sep 12, 2013
    Posts:
    13
  12. fafase

    fafase

    Joined:
    Jul 3, 2012
    Posts:
    163
    Last edited: Aug 28, 2015