Finite State Machines with Unity3D – Part 3

Hierarchical state machines are used to organize states within states. So basically we have a state machine that will have other state machines inside states. For example let’s think of a soccer game. We can define clearly two sets of behaviours for soccer players: attacking and defending. Since these behaviours can be very complex it would make sense to have a state machine that would contain the attacking and defending states, each state having a different sub state machine.

If we decided to implement the basic state machine structure inside a FlexState, as described in the first part of this series, we would have a hierarchical state machine in place. But that’s fairly obvious, what we would like to have in a relatively complex scenario is a FlexFSM inside a state.

To make this happen we will have to use an extra method as an override that already belongs to the FlexState class; Configure. This method is called whenever a class is added to a FlexFSM and it’s suitable to contain the code for the sub state machine instantiation. The reasoning behind this is because we need to get a reference to the root FlexFSM and the safest way is to ask for it inside the state.

Let’s continue with the soccer player example to make things clear.

First, the root FSM, which will contain the two “top-level” states: Attacking and Defending.

As for the states managed by the Attacking and Defending sub-FSM’s they are just normal states. Note that we keep using namespacing for a better organization. So, for the SoccerPlayerDefenseStates , we could have something like this.

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

usingSystem;

usingSystem.Collections.Generic;

usingUnityEngine;

usingSystem.Collections;

namespaceSoccerPlayerDefenseStates

{

publicenumStateID

{

Idle,

FollowingBall,

ReturningToDefensePosition,

Frozen

}

//========================================================Idle

//============================================================

publicclassIdle:FlexState

{

publicoverridevoidOnEnter(GameObject owner)

{

}

publicoverridevoidOnExit(GameObject owner)

{

}

publicoverridevoidReason(GameObject owner)

{

}

publicoverridevoidAct(GameObject owner)

{

}

}

//Rest of states...

}

In the next article we will close the state machine topic talking about blip states and how to provide a clean way for external communication with the active state of a FlexFSM.