Finite State Machines [Part 3]

Here’s our final blog tutorial for the FSM. We will review what we’ve discussed on the first part, and implement the FSM System that we did before.

Just a recap on the previous parts:

sOSpPXe__WTretdttbvYesQ

This will be the loop of our FSM. First we initialize the FSM, create states, create actions, and map them all together. After we have mapped them, we will now start the FSM and indicate the state that the AI will start to. Now, the AI will change to a specific state, and the FSM will initialize the action, update it until it the action finishes and sends an event indicating that the action is finished. Finally, the FSM will go back and change the state.

Now it’s time to implement them.

Text Action

Let’s create a TextAction so that we’ll see the FSM System first hand.

1FReRU4CWYFVPXTHKa65PQqfu7VQx6nJ3poP4_6A

Let’s first import the Common.FSM so that we could use our FSM system, and let this class inherit the FSMAction class.

Let’s now write the variables and constructor for this specific action.

textToShow is the string that we will print out in the console when updating. Duration is the length of this action, and the finishEvent is the call to transition to another state.

Let’s override the virtual functions of the FSMAction so that the FSM could call them.

OnEnter will handle all the things that we want to do when starting an action. Just like a Start() in MonoBehaviour, we will initialize our action at this stage. Update will be called by the FSM’s action processor, that is called by the FSM’s Update function, and that is called by our AI’s class. On exit of course, will be the things that we will do when we finishes an action. Personally, I’d rather have a finish function that will send the event.

AI Implementation

Now that we’ve made an action, let’s make an AI.

1vBWCxCqzAGoyCv4XThrLnrhqyVKfgTpDvPZN4Tk

Let’s create an empty that will hold our AI script.

1fHeGwtXW1jPMC7ezRqHJpHrrztNsHa7yKHwb3q4After creating an empty, let’s create a script that will implement our FSM system and the action that we made.

Let’s make two FSMStates and two FSMAction for our AITest. Don’t forget to import Common.FSM or we won’t be able to use the FSM system that we’ve made.

Again, fsm will be the engine of our state machine, we will have two kinds of state, PatrolState, and IdleState. It’s up to you how you want to name them. Lastly, we will have two text actions, one for each state, PatrolAction, and IdleAction.

Let’s now create the FSM, States, and Actions in the Start() function.

First, we will initialize the FSM, then add new states. Remember, FSM.AddState() returns FSMStates so that we won’t have to declare a new FSMState, and add them to the FSM.

Now that we have states and action, let’s now map everything, and add event ids to every transitions.

We mapped the PatrolState to IdleState when an event was sent to the state and vice versa. Let’s now initialize our actions.

The first property which is a string, will be the output of our action, the second one will determine the duration of the action, and the last property will be the event that it will send out after the action is finished.

Keep in mind that everything here is inside the start function. Let’s now try and make the FSM work by calling the FSM.Start() and FSM.Update();

Again, fsm.Start() is called after all initialization under the Start(). Now let’s attach the AITest to the empty game object that we created earlier and press Play in the editor.

Now finally, watch the automation happens!

1s-7f6nFEDuhmfFSXjaXAk0_Fh0Jyhs1P_N6EKsQAI will print out Idle for every 2 seconds and will Patrol every 3 seconds.

Moving Action

1VwqSEDvSaDRP50DJsCX2w-dso9Bch-lcqp0D9y8Now let’s take it to another level. Let’s make a moving object and at the same time, printing out strings in the console. But we’re not going to do it in one action. We’ll be creating another action that will be added to the same state.

Let’s make another script called AITestTwo.

1IU-GFRQu-tgoJLrMoM_GZ2SxE0rq6sMd5cfswRALet’s create another action called MoveAction. This will be a generic action for moving object.’

Open up the MoveAction.cs and let’s write the action.

 

MoveAction.cs is different, we have to have a reference to the object’s transform so that the action could move it.

 

Let’s discuss the properties. As I said above, we will need to have the object’s transform to be referenced in this action since we want THIS action to move the object, NOT the AI Class. Pretty self explanatory, Vector3 from, and to. Again, duration of the action, and the finish event.

As you see there, we have two variables that aren’t included in the Init() properties which is the journeyLength, and polledTime. We will use them for our Vector3.Lerp function later on. The polled time will be included in our calculation later on.

Now we added a helper function for position which is the SetPosition() to make things easier for us. Again, OnEnter() initializes the action, the OnUpdate() will be the one that will execute the Lerp function. This is also where we will calculate the ratio that is needed for the Lerp function. When the action finishes, we will set the object to the desired final position, and reset our variables.

Multi-action Implementation

Now, let’s go and set up the second AI.

We now have two actions for each state. The FSM will now update two actions in one state. What we did here is just the same from what we did on the TextAction.cs. We made instances of the classes, added the actions to states, and added transitions and calls to those states, and initialized the actions.

Now let’s hit play and hope that it works properly.

1KDFzVJldz17rgpUe8XPO884SAYqx5JYzd5D8jaA

1RmIMDg8oKBNpn_2JPWFTLf1FNPbdbYj0YmMe4Ic

As you can see, the AI is now doing the actions at the same time. You can mix different actions and add them dynamically to your desired state.

What’s great about this is that you can add a lot of actions and contain them into one state and do them simultaneously. Although it will cause you some performance issues if you’re on mobile. What I suggest is that, when you use it for mobile, just do at least 1 or 2 actions simultaneously just for safety. I haven’t done real tests for mobile though.

So there it is, we have concluded our Dynamic FSM tutorial. I hope that this will become helpful for your games. You could use this in any game, in any way. Whether you use it on UI, GameObjects, or whatever fits your needs. Please do remember to comment if you have any questions, I am happy to send a reply as soon as I can!

FSM is a really big topic to cover in three parts, so here are few of the FSM-related articles and implementations if you want to understand it a little better. I believe these will explain FSM much further:

This is the link for the unity package if you want to see the whole project.

This is the link for the scripts that we made all throughout.

Finite State Machines [Part 2]

Deeper inside FSM

Finite State Machines are a sequential logic that are very low level. They can be used for simple decision-making logic. Let’s give a human example of an FSM:

  • Input: Flips the switch
  • State: Light Bulb is in the state of “On”
  • Output: Light Bulb will now produce light for the room

Inputs are any form of stimulus from the user that can trigger a change of state based on the condition needed to perform that states. Think about switching a light on:

States as you can see, describes the current condition of the FSM. Until the user makes another input, the light bulb won’t change its state to “Off”.

Outputs are linked to the FSM’s state depending on how the FSM is programmed by the programmer.

FSM Implementation

This is my way of implementing a dynamic FSM in Unity. This will require us to have the main FSM class per object that holds the states; FSM State for the object that holds the actions;  and FSM Actions that does the outputs of the state.

Now that we’ve introduced the FSM to you, let’s now do some scripting. Let’s do them one by one. First, let’s organize our unity project.

fsm1It’s up to you where to place them. I always separate my game-only-assets to other assets. We’re going to put this FSM in our common folder(I always have the “Common” folder because I have my own library that I use in every games) because this FSM system will be dynamic and you will be able to use everything to every games.

The reason why we have a folder for actions is to compile all the actions that we make, and create a library of actions for other kinds of games.

Let’s now create our main FSM class, and put it in the FSM folder under common, and let’s call it FSM.cs.

FSM.cs

Couple of things, I’m a namespace fanatic and it’s a great practice to segregate your codes if you’re not using any of them. Again, I have my Common library which is why I placed it under Common. You can create your own namespace if you want to.

As you can see, we’re not inheriting from MonoBehaviour class because we will have an update function that will be called under the AI’s update instead to update the FSM.

Now let’s make some variables and functions for our FSM.

Just a tip, if you think that the code is starting to look dirty because of all the summary, just enable the code colding of monodevelop. Just go to Tools/Options/Text Editor/General, and check “Enable Code Folding”

1f6YhKn0Eab-kWruxMd5SxtZwbhJ3QJ0etcD6jlg

Now we can fold the summaries in the code itself.

142BcsOI5X_HbKXwAr70JOlyX13ApnXzOxFkFyZM

Before we go any further, let’s create the FSMState, and FSMAction because we need to create functions in the FSM that will return them. Let’s start with the FSMAction.

FSM Action Impementation

FSMAction will be the base class of our actions, hence the virtual functions. If you’re not familiar with virtual functions, here’s a Unity Tutorial that talks about Polymorphism.

Initial FSM State Implementation

Let’s now start the FSMState and let’s call this FSMState.cs:

Now that we’ve started on everything, let’s finish up the FSM class.

Finishing FSM Implementation

Let’s add the ff variables in our class.

The name of course will be the name of the FSM. The stateMap will contain a key which will be the event id of the FSMState, and the FSMState itself so that we could bind them together, and transition to another state via SendEvent() function.

Of course the name of the FSM.

We will create an action processor. This will enable us to dynamically call different actions that is inside the state, and do the action. If you’re not familiar with delegates, refer to this.

Let’s now fill up the constructor that we did before and make an initializer for our FSM.

Constructors as you know, makes creating instances of classes easier and much more clean, and less coupled since the variables of this class are set to private. Keeping unnecessary variables unseen for the other programmers.

We will now add a FSMState parameter to ChangeToState(), EnterState(), and ExitState()

Now it’s important to check the states to avoid jumbling them and avoid errors.

Enter, Exit, and Update will be the same and will be handled by our action processor.

Finishing FSM State Implementation

Now that we’ve created our loop. Let’s start writing our FSMState. First its constructor.

Before we go any further, let’s talk about transitions. Transitions by its name, is the change between two states. We’ll use a string to act as a key to change between states. All of these are contained in a dictionary.

Now let’s make a function that adds actions to our state.

Let’s now add the event handlers for the FSM, and the FSMState. Let’s first go back to the FSM.cs and add new functions to the class.

Let’s finalize the FSMState by adding implementations for event handling.

Lastly, let’s create a function that will automatically create states for us under FSM.cs.

By calling this function, this will enable us to create States without creating on the AI class itself.

So there you have it. Our FSM system is now done. Look out for our next Blog tutorial for the implementation. Please do comment if you have questions regarding this topic.

On the next and final part of this tutorial, we will make two kinds of implementations for this FSM engine that we made. We will create one AI class that will write to our console indefinitely, and another AI that will move AND write to our console indefinitely.

Finite State Machines [Part 1]

Finite State Machines might be something that all developers might have heard at least once in their few years starting game development in Unity.

What is a Finite State Machine anyway? Well, there is a lot to cover that is why we’re going to do at least 3 parts. Basically, a Finite State Machine (or FSM) is a design pattern where automation comes in play. Commonly used in AI implementations for certain behaviours. Ie: Walking, Attacking, Idling, etc. FSM can be also implemented in NPCs and is most common in Open World RPGs.

fsm1Let’s treat FSM as an overseer:

Now, the overseer checks the state of an AI. Depending on the state, the AI will react on it. Also, depending on the type of an AI (whether it is a flying type, or ground type, or swimming type) is the action that the AI will make. In this scenario, FSM tells the AI that he is in the “Patrol State”, and will tell the AI to “Walk from A to B”. Unless that there’s a change in state, the AI will only walk from A to B.

fsm2

 

To change state, first we must have a condition. In the image on the left, the AI sees the player, and tells the overseer. Now the overseer will change the AI’s state, and will start attacking.

 

 

1ZmLLoS1bAl71Ea_BNZzHWaja5YsjvqLa2z-ubNYAgain, the AI starts to patrol again since the player is not in his line of sight.

As seen in these poorly made drawings, every state has their conditions before changing to other states.

Let’s look at the diagram below.

 

 

 

sNz-b43jHw-bZzuRbNlrvHQ

Here is a diagram of states of a normal AI. Red lines represents false on the condition that is required to change in state. The diagram is pretty straight forward. The AI will be on Idle State if it reaches its destination, and vice versa. If he sees an enemy, it will start to attack. The FSM now handles all transitions between states and helps the AI do the action that is available for that state.

Now let’s break down our FSM System.

  • Main FSM System – This is will be the one who will control the AI’s states and checks if the conditions between states. The Main FSM will contain all the states, and will handle the event calls from the FSM Actions.
  • FSM State – This determines the current state of the AI and contains all the actions that is placed on the AI.
  • FSM Action – This will be the action that the AI will do when the AI is in a specific state.

Now how will we do it? Let’s map everything out.

sV8-Gi7zqfM4YoWEXA-SCGw

This will be the loop of our FSM. First we initialize the FSM, create states, create actions, and map them all together. After we have mapped them, we will now start the FSM and indicate the state that the AI will start to. Now, the AI will change to a specific state, and the FSM will initialize the action, update it until it the action finishes and sends an event indicating that the action is finished. Finally, the FSM will go back and change the state.

Another thing that will cause a change of state is when an event is called outside the AI’s logic. Like when we create a commander and tells all the soldiers to stop moving.

This ends the first part of our FSM tutorial. I hope that I’ve explained FSM well to you. If you still don’t get it, probably you’ll need to see everything in action first, and see scan everything for yourself. That’s how I learned it.
On the next part, we will first discuss again some simple real life FSM implementations, and we will start scripting our whole FSM Engine from scratch!