Unity : AI && NavMesh [FSM : (Finite State Machine with Enum)]
This is a BIG topic. The FSM is one of the most useful and use design pattern in video games (it call even State Pattern).
Its implementation has various form, one of them is with Enum and a switch Statement.
Now, the real Satte Pattern is not with enum, but it’s more advance, when the enum implementation is more “understandable” at the beginning and is less complicated to use.
For now we use the enum implementation, just to understand how it works.
So at the top we create an enum AIState, and we creae for example four State : Walking, Jumping, Attack and Death.
To access to it, we create a variable AIState called currentState.
And if we [SerializeField] this variable, in the editor we have a drop down menu to visualize in what State we are.
To use it directly in code, we need the Switch Statement, based on currentState.
NOTE : there is an incredibly useful shortcut to create switch statement with all the cases inside.
Type sw and Intellisense understand we want a switch statement, then press TAB two times, it opens a full declaration
Now inside we pass our variable _currentState, and press two times Enter
Ok, now that we have a switch, we use a Debug.Log() to see how it works.
To test it with a little more “implementation” of logic, we can do this
Inside AIState.Walking we pass directly our CalculateAIMovement()
Then, we add a check, for example if we press Space Bar, to go from Walk to Jump State.
If we test it and look in the editor
We press the Space Bar, and because we pass from Walk to Jump, we see that the state of AI changes.
And because the Jump state is literally empty, there is only the Debug.Log(), the AI is stop moving, because we are now in the Jump State, while the movement it’s inside the Walk state.
With these concepts in mind, we can expand our logic to, well, everything we want.
For example, we can make AI move until reach a point, perform an Attack, wait for 3 seconds and restart.
And with this implementation is easy to do and understand how make it works.
Let’s try it!
First, we need a Coroutine.
Every time we manage something with time probably we use a Coroutine.
So we create an AttackRoutine().
This is a simple test, not real implementation, so we simply arrive at point, stop, wait 3 seconds and move again.
After that we need a create something to tell us
“Ehi, we now are in the Attack state”.
We need this check for a really good reason :
if the Coroutine is called before it finishes executing its code, it resets itself from the beginning.
To handle this we use a bool.
And we use this bool inside Attack State and set the bool to TRUE
In this way, when we enter in the Attack State && the bool is FALSE, we start the Coroutine.
But we need to rest the bool after Coroutine is finish, so inside the AttackRoutine(), at the end, we reset the bool to FALSE.
And we don’t forget to call the Attack state inside CalculateAIMovement()
If we test it now
We see in the next articles!