Programming Finite State Machines in Unity3D using C#
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.
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