Working a finite-state machine

Another interesting yet easy-to-implement technique is finite-state machines (FSM). They move us to change the train of thought from what it was in the previous recipe. FSMs are great when our train of thought is more event-oriented, and we think in terms of holding behavior until a condition is met changing to another.

Getting ready

This is a technique mostly based on automata behavior, and will lay the grounds for the next recipe, which is an improved version of the current one.

How to do it...

This recipe breaks down into implementing three classes from the ground up, and everything will make sense by the final step:

  1. Implement the Condition class:
    public class Condition
    {
        public virtual bool Test()
        {
            return false;
        }
    }
  2. Define the Transition class:
    public class Transition
    {
        public Condition condition;
        public State target;    
    }
  3. Define the State class:
    using UnityEngine;
    using System.Collections.Generic;
    
    public class State : MonoBehaviour
    {
        public List<Transition> transitions;
    }
  4. Implement the Awake function:
    public virtual void Awake()
    {
        transitions = new List<Transition>();
        // TO-DO
        // setup your transitions here
  5. Define the initialization function:
    public virtual void OnEnable()
    {
        // TO-DO
        // develop state's initialization here
    }
  6. Define the finalization function:
    public virtual void OnDisable()
    {
        // TO-DO
        // develop state's finalization here
    }
  7. Define the function for developing the proper behavior for the state:
    public virtual void Update()
    {
        // TO-DO
        // develop behaviour here
    }
  8. Implement the function for deciding if and which state to enable next:
    public void LateUpdate()
    {
        foreach (Transition t in transitions)
        {
            if (t.condition.Test())
            {
                t.target.enabled = true;
                this.enabled = false;
                return;
            }
        }
    }

How it works...

Each state is a MonoBehaviour script that is enabled or disabled according to the transitions it comes from; we take advantage of LateUpdate in order not to change the usual train of thought when developing behaviors, and we use it to check whether it is time to transition to a different state. It is important to disable every state in the game object apart from the initial one.

How it works...

There's more...

In order to illustrate how to develop child classes deriving from Condition, let's take a look at a couple of examples: one that is aimed at validating a value in a range and the other one at being a logic comparer between two conditions:

The code for ConditionFloat is as follows:

using UnityEngine;
using System.Collections;

public class ConditionFloat : Condition
{
    public float valueMin;
    public float valueMax;
    public float valueTest;

    public override bool Test()
    {
        if (valueMax >= valueTest && valueTest >= valueMin)
            return true;
        return false;
    }
}

The following is an example of code for ConditionAnd:

using UnityEngine;
using System.Collections;

public class ConditionAnd : Condition
{
    public Condition conditionA;
    public Condition conditionB;

    public override bool Test()
    {
        if (conditionA.Test() && conditionB.Test())
            return true;
        return false;
    }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.186.109