Finite State Machines with Unity3D – Part 1

The state pattern is an easy way to structure code in-game programming since most of the games mesh well with the idea of states and transitions. This pattern is often implemented as a finite state machine, being finite the number of states.

Let’s see a simple example:

This simple state machine defines the behavior of a, rather dumb, enemy entity. We can differentiate states in which the enemy will be (one and only one at any given time) and conditions that will trigger state changes (transitions).

If we put the diagram into code, we could end with 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

40

41

42

43

44

45

46

47

48

49

50

51

publicclassEnemyBehaviour:MonoBehaviour

{

enumState

{

Wandering,

FollowingPlayer

}

privateGameObject player;

privateState state;

privateWander wander;

privateFollow follow;

voidStart()

{

wander=GetComponent();

follow=GetComponent();

state=State.Wandering;

}

voidUpdate()

{

switch(state)

{

caseState.Wandering:Wandering();break;

caseState.FollowingPlayer:FollowingPlayer();break;

}

}

privatevoidWandering()

{

wander.Do();

if(IsOnRange(player))

{

state=State.FollowingPlayer;

}

}

privatevoidFollowingPlayer()

{

follow.Do(player);

if(!IsOnRange(player))

{

state=State.Wandering;

}

}

privateboolIsOnRange(GameObject _player)

{

//code

}

}

As you can see states are well-defined, and each state will check for conditions to change state. More importantly, the code reads well, always aim for thin states, and extract code related to the logic that drives the behavior implementation into other classes when possible.

A clean code state machine should be about giving orders and choosing when to change state.

But even if you try to keep states as thin as possible it’s obvious that, unless you are doing something very simple, it’s going to be necessary refactoring states to separate classes and building a system that can manage these states into a well-structured state machine.