Objective: Creating a Finite State Machine (FSM) to control the AI Agents behaviour.
First of all we have to ask ourselves what is an FSM?
A Finite State Machine is where a game designer creates all the possible situations an AI Agent could possibly encounter and then program a specific reaction to each of the situations.
E.g. Walking, running, attacking, defending.
All of these situations can then have some logic built into them so the AI can decide which state it needs to be in e.g. If the player is not within 3 metres of the enemy — Patrol. However, if the players distance comes within the 3 metres, change the AI Agents state to Attacking. If the AI Agent then takes a lot of damage from the player, there might be some logic build around Defending e.g. If health is < 50, check AI’s inventory to see if they have a health potion and if so drink it.
Creating An FSM For Our AI Agent
Let’s create a simple FSM for our AI Agent which will have the following states: walking, jumping, attacking and dying.
To create our FSM let’s use an Enum:
Let’s then set the initial state of the AI Agent to ‘walking’:
Now let’s create the capability to switch between these states:
Note: Having this code in Update() is not ideal but works well for our purpose!
Starting simple, let’s build logic to change to the ‘jumping’ state:
Using the existing code from the previous article, let’s add one line of code (AIState to Attacking) to the logic so that when the AI Agents remainingDistance is < 0.25f we want them to stop moving and start attacking for 3 seconds before moving onto the next target:
As we are dealing with delaying time, let’s build a coroutine to assist us with the logic and make sure to call this in the ‘Attacking’ state.
We only ever want one of these coroutines to be running at a time so let’s cache it inside a variable and null check. If it is null, assign the StartCoroutine() method to it. We will reset this back to null at the end of the coroutine.
Instead of using ‘yield return new WaitForSeconds(3F)’; for optimisation purposes let’s cache this as we are going to be constantly calling it.
Make sure to tell the AI Agent to stop moving by setting the ‘isStopped’ property to true.
Once the coroutine has yielded for 3 seconds, it will then set the AIState back to ‘Walking’ and start moving the AI Agent again.
The last crucial part is that we need to make sure we are setting the Coroutine ‘_co’ back to null so the coroutine can run again.
Building a NavMesh — Unity Documentation
NavMeshAgent — Unity Documentation
NavMeshAgent component — Unity Documentation
Agent.destination — Unity Documentation
Agent.remainingDistance — Unity Documentation
Setting Up a NavMesh in Unity — Article
Moving Agents on a NavMesh in Unity — Article
Creating a Looping NavMesh in Unity — Article
“Generating Offmesh Links for AI in Unity”