Programming Finite State Machines in Unity3D using C#

09 Oct 2010
Posted by xeophin

Finite State Machines are quite a convenient design pattern in Game Design, as they allow for quite some flexibility when programming AI behaviour.

Unfortunately, our first encounter with FSMs was poorly explained, and badly executed in ActionScript 3 using a bunch of switch statements – disregarding the fact that there would have been clearly more elegant solutions.

So, let's do the same for Unity 3D in C#, using delegates.

using UnityEngine;
using System.Collections;
 
public class FiniteStateMachine : Monobehaviour {
 
    // Create the delegate
    private delegate void FState ();
 
    // Create a holder for the delegate
    private FState stateMethod;
 
    #region UnityEngine methods
 
    /// <summary>
    /// Sets up the controller and puts the object into the new mode.
    /// </summary>
    void Start ()
    {
        stateMethod = new FState (EnterStateA);
    }
 
    /// <summary>
    /// Executes in every frame once. Only calls the current state method.
    /// </summary>
    void FixedUpdate ()
    {
        stateMethod ();
    }
 
    #endregion
 
    #region State A
 
    /// <summary>
    /// Sets up State A.
    /// </summary>
    private void EnterStateA () {
        // Things to prepare State A come here.
 
        stateMethod = new FState (StateA);
 
        // The next line will ensure that the first run of State A
        // will occur in the same frame. Commenting this line out
        // will delay execution to the next frame.
        stateMethod();
    }
 
    /// <summary>
    /// The actual state that is being repeated every frame.
    /// </summary>
    private void StateA () {
        // Code goes here ...
 
        // Conditions to switch into another state go here
 
        if (someConditionApplies ()) {
            stateMethod = new FState (EnterStateB);
            ExitStateA ();
        }
    }
 
    /// <summary>
    /// Clean up method for state A.
    /// </summary>
    private void ExitStateA () {
        // All the stuff that needs to be cleaned up comes here.
    }
 
    #endregion
 
    #region State B
 
    /// <summary>
    /// Sets up State B.
    /// </summary>
    private void EnterStateB () {
        // Things to prepare State B come here.
 
        stateMethod = new FState (StateB);
 
        // The next line will ensure that the first run of State B
        // will occur in the same frame. Commenting this line out
        // will delay execution to the next frame.
        stateMethod();
    }
 
    /// <summary>
    /// The actual state that is being repeated every frame.
    /// </summary>
    private void StateB () {
        // Code goes here ...
 
        // Conditions to switch into another state go here
 
        if (someConditionApplies ()) {
            stateMethod = new FState (EnterStateA);
            ExitStateB ();
        }
    }
 
    /// <summary>
    /// Clean up method for state B.
    /// </summary>
    private void ExitStateB () {
        // All the stuff that needs to be cleaned up comes here.
    }
 
    #endregion
}

Of course, this code can be extended with further states (in my current project, I have three distinct states).

And of course, adding another private FState somethingOther allows for yet another chain of behaviour that is independent from the first.

[1]: /blog/2010/05/18/dynamically-referencing-variables-and-methods-actionscript[2]: http://msdn.microsoft.com/en-us/library/ms173171(VS.80).aspx[Finite State Machines](http://en.wikipedia.org/wiki/Finite-state_machine "Finite-state machine - Wikipedia, the free encyclopedia") are quite a convenient design pattern in Game Design, as they allow for quite some flexibility when programming AI behaviour.Unfortunately, our first encounter with FSMs was poorly explained, and badly executed in ActionScript 3 using a bunch of switch statements – disregarding the fact that there would have been [clearly more elegant solutions][1].So, let's do the same for Unity 3D in C#, using [delegates][2].using UnityEngine;using System.Collections;public class FiniteStateMachine : Monobehaviour { // Create the delegate private delegate void FState (); // Create a holder for the delegate private FState stateMethod; #region UnityEngine methods /// /// Sets up the controller and puts the object into the new mode. /// void Start () { stateMethod = new FState (EnterStateA); } /// /// Executes in every frame once. Only calls the current state method. /// void FixedUpdate () { stateMethod (); } #endregion #region State A /// /// Sets up State A. /// private void EnterStateA () { // Things to prepare State A come here. stateMethod = new FState (StateA); // The next line will ensure that the first run of State A // will occur in the same frame.

Is there a way to pass a

Is there a way to pass a parameter to these state methods, like this?: stateMethod = new FState (StateA(1));


Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account associated with the e-mail address you provide, it will be used to display your avatar.
By submitting this form, you accept the Mollom privacy policy.


Navigation



Languages


Syndicate

Syndicate content