Finite state machines

Hi.

I started programming in C# a few weeks ago and this is pretty hardcore stuff for me, some guy in unity answers sugested me I could use a FSM engine for my game so I searched the internet, found a few good sites with information about it (Unitygems.com) readed all I could read and I think I have a better understanding of what is this about. I think the concept its pretty simple and its pretty much based in logic

How I understand it (I could be totally wrong!):

Lets say we have an enemy, this enemy is in idle until the player gets close enough, when the player is close enough the enemy starts chasing the player, when the enemy reaches the player it attacks the player, so to my undestanding that would be 3 “states” the enemy has.

  • Idle
  • Chasing player
  • attacking

(Dont laugh at my microsoft paint skills!)
1145529--43442--$FSMs.jpg

FMS: Hey Mr.Enemy what are you up to?
Enemy: Idle
FMS: its the player close enough
Enemy:yes
FMS: then move towards the player and change state to “chasing player”

Thats the concept I got from reading about it (and I probably got it wrong).

However as much as i think I understand the basic concept the implementation and the code its what gets me, for example I want to have an inventory system for my game like in the old resident evil games.

In the inventory you can check, combine, use,etc the Items

Also in my game you can use two weapons at the time, one by default (regular left mouse button fires it) and other you can use by holding the right mouse button (while holding right mouse button and click on left mouse button fires it).

In the game there are three basic animations idle, run and jump

Each weapons has its own versions of these animations so I think idle, run and jump should be player states, and “item” or “weapon” should be too so the inventory system can identiffy what an object is but I dont know.
also should this be done in one script like a FMS that manages all the states of every object or should I have separate scripts for example one for objects weapons, other for like the inputs and so on?

Could also someone show me really simple FSM scripts(the ones on unitygems.com are really complex) , I would like to know how this things are done and how they interact with each other. The scripts doesnt need to work actually, it could be just descriptive code to see how things work.

Thanks

Hello,

try not to think this will be an easy task. What you have written are complete features that would be a long term task even for a fit programmer. I recomment you to get deeper into the topic of StateMachines and first of all just to use Debug.Log() to track the state changes.

Now what you were asking for is:

  1. What you Need: 1 class for entity(e.g. enemy or whatever), 1 Base class State which does only contain one public virtual function Execute. Then you need several classes that are derived from the State class and override the Execute function with their own contents.

here’s an example:

using UnityEngine;
using System.Collections;

public class EnemyDude : MonoBehaviour // separate file
{
	public bool PlayerisNearby;
private State state;
	
	void Start(){
	state = new Idle_State();	
	}
	
	void Update(){
		state.Execute(this);	
	}
	
	
	public void SwitchState(state newstate){
		state = newstate;	
	}
}


public class State(){ // separate file
	
	public virtual void Execute(EnemyDude dude)
	{
		
	}
}

public class Idle_State : State(){ // separate file
	override void Execute(EnemyDude dude)
	{
	if(dude.PlayerisNearby){
		dude.SwitchState(new ChasePlayer_State());	
		}
	}
}
				
public class ChasePlayer_State : State(){ // separate file
	override void Execute(EnemyDude dude)
	{
	if(dude.isCloseEnoughButNotNearEnoughToFight){
		dude.RunToThePlayer();
		}else{
		 dude.SwitchState(new Idle_State());	
		}
	}
}

I didnt test it, but you should get the idea. Enemydude is always executing a state and the state in which he currently is decides when he has to do something else(switchstate).

What it would do: Idle, if player nearby chase player, if player is again to far away, do again some idle.

Cheers

If you have the trouble understanding FSM logic then you should reproduce all the stuff they are doing in UnityGems. Then you should come to some understanding.

The core idea behind FSM is to separate the game object logic for each behaviour case to make it understandable and maintainable. When done right, it allows to avoid sophisticated nested constructions and spaghetti code.

There could be as much FSMs in the game as needed. I don’t know, how it’s done in Resident Evil, but your inventory can have states such as: idle, inventory object selected. So when your inventory enters idle state (you can make a separate method to handle “enter idle” case), you can lock all your action buttons, and when your inventory enters “object selected” state, you can unlock them. You can also lock them in “exit object selected” handler.

FSM is just a good way to organize these “enter”, “exit” and, maybe, “update” handlers in a convenient way. That’s what UnityGems articles are about.

Thanks for your response, lets see If I can get this

Sorry if my questions are too stupid but this is like a middle man right? why there is a need for this?

public class State(){ // separate file

    

    public virtual void Execute(EnemyDude dude)

    {

        

    }

}

I see this example works for stuff like a chain (like states that executed one after another, like in my example) but how about if more than one states where posible and the the enemy has to decide in what state is he in? Im guessing, I should have like a weight or a priority system for states?

Like for example, conditions for state 1 state 2 are met, state 1 has a weight of 3 and state 2 a weight of 5, state 2 has more weight therefor state 2 is executed first

Ok I think i get it now, this is the actual state and it gets overrided by the other classes (Chaseplayer and idle)

public class State(){ // separate file

    

    public virtual void Execute(EnemyDude dude)

    {

        

    }

}

I like this, you can expand it by adding more classes to it. Ok time to try this on my own.

for me as a beginner this looks fairly easy to grasp however, could someone please tell me how I could implement a pause between each state call, maybe using an IEnumerator?

this is what I have so far and it seems to work, is there a better way?

TestFSM.cs

using UnityEngine;
using System.Collections;

public class TestFSM : MonoBehaviour // separate file
{
    private TestStates state;

    public bool alive;
  
    void Start(){
        alive = true;
        state = new TestState1();
    }
  
    void Update(){
        if(alive) {
            state.Execute(this);
        }
    }
  
    public void SwitchState(TestStates newstate){
        alive = false;
        StartCoroutine(Waiting (newstate));
    }

    public IEnumerator Waiting(TestStates newstate) {
        Debug.Log ("in waiting, next state is: " + newstate);
        yield return new WaitForSeconds(2f);
        alive = true;
        state = newstate;
    }

}

TestStates.cs

public class TestStates
{ // separate file

    public virtual void Execute(TestFSM dude)
    {
    }
}

TestState1.cs

using UnityEngine;
using System.Collections;

public class TestState1 : TestStates
{
    public override void Execute(TestFSM state)
    {
        Debug.Log ("im in state1!");
        //if(dude.PlayerisNearby){
            //dude.SwitchState(new ChasePlayer_State());
        //}
        state.SwitchState(new TestState2());
    }
}

TestState2.cs

using UnityEngine;
using System.Collections;

public class TestState2 : TestStates
{
    public override void Execute(TestFSM state)
    {
        Debug.Log ("im in state2");
        //if(dude.PlayerisNearby){
        //dude.SwitchState(new ChasePlayer_State());
        //}
        state.SwitchState(new TestState1());
    }
}