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.
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.
This recipe breaks down into implementing three classes from the ground up, and everything will make sense by the final step:
Condition
class:public class Condition { public virtual bool Test() { return false; } }
Transition
class:public class Transition { public Condition condition; public State target; }
State
class:using UnityEngine; using System.Collections.Generic; public class State : MonoBehaviour { public List<Transition> transitions; }
public virtual void Awake() { transitions = new List<Transition>(); // TO-DO // setup your transitions here
public virtual void OnEnable() { // TO-DO // develop state's initialization here }
public virtual void OnDisable() { // TO-DO // develop state's finalization here }
public virtual void Update() { // TO-DO // develop behaviour here }
public void LateUpdate() { foreach (Transition t in transitions) { if (t.condition.Test()) { t.target.enabled = true; this.enabled = false; return; } } }
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.
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; } }
18.189.186.109