How should I go about structuring a finite state machine if I need to make use of all three update functions?

Normally when I have an enemy that I need to write AI for, I’ll use a finite state machine, like the one shown below:

public class SomeEnemy : Monobehaviour
{
	public enum States {searchingForPlayer, chasingPlayer, attacking, recovering};
	private States currentState = States.searchingForPlayer;
	
	
	void Update()
	{
		FiniteStateMachine();
	}
	
	//Finite state machine-related functions
	
	private void FiniteStateMachine()
	{
		switch (currentState)
		{
			case States.searchingForPlayer:
				WhileSearchingForPlayer();
				break;
				
			case States.chasingPlayer:
				WhileChasingPlayer();
				break;
				
			case States.attacking:
				WhileAttacking();
				break;
				
			case States.recovering:
				WhileRecovering();
				break;
		}
	}
	
	private void WhileSearchingForPlayer()
	{
		//Insert code here that checks to see if a player is in range
		if (playerIsInRage)
		{
			currentState = States.chasing;
		}
	}
	
	private void WhileChasingPlayer()
	{
		//Insert code here that checks to see if the player is within attacking distance
		if (caughtUpToPlayer)
		{
			currentState = States.attacking;
		}
	}
	
	private void WhileAttacking()
	{
		//Attacking animation here
		if (animationIsOver)
		{
			currentState = States.recovering;
		}
	}
	
	private void WhileRecovering()
	{
		//Insert code here that waits for a while and then goes back to the searching state
		if (doneRecovering)
		{
			currentState = States.searchingForPlayer;
		}
	}
}

In most cases, this works really well. It helps me turn big problems into smaller, more manageable problems. Unfortunately, is has an obvious downside: it ends up making the code REALLY long. It’s still pretty manageable when I only have a few states and only make use of the normal Update() method.

But recently, I’ve run into a problem: I have an object that requires me to use all three of the update methods for each state. This means that when I have to add a new state, I need to create not one, but THREE methods devoted to this one state: one for Update(), one for FixedUpdate(), and one for LateUpdate(). I then have to remember to add each of those methods to TRHEE different switch-statements. With one or two states, I can manage it. But when I need to add four or more states, it becomes really messy really quickly.

It would turn the previous example into one looking like this:

public class SomeEnemy : Monobehaviour
{
	public enum States {searchingForPlayer, chasingPlayer, attacking, recovering};
	private States currentState = States.searchingForPlayer;
	
	
	void Update()
	{
		FiniteStateMachine_NormalUpdate();
	}
	
	void FixedUpate()
	{
		FiniteStateMachine_FixedUpadate();
	}
	
	void LateUpdate()
	{
		FiniteStateMachine_LateUpdate();
	}
	
	//Finite state machine-related functions
	
	private void FiniteStateMachine_NormalUpdate()
	{
		switch (currentState)
		{
			case States.searchingForPlayer:
				WhileSearchingForPlayer_NormalUpdate();
				break;
				
			case States.chasingPlayer:
				WhileChasingPlayer_NormalUpdate();
				break;
				
			case States.attacking:
				WhileAttacking_NormalUpdate();
				break;
				
			case States.recovering:
				WhileRecovering_NormalUpdate();
				break;
		}
	}
	
	private void FiniteStateMachine_FixedUpdate()
	{
		switch (currentState)
		{
			case States.searchingForPlayer:
				WhileSearchingForPlayer_FixedUpdate();
				break;
				
			case States.chasingPlayer:
				WhileChasingPlayer_FixedUpdate();
				break;
				
			case States.attacking:
				WhileAttacking_FixedUpdate();
				break;
				
			case States.recovering:
				WhileRecovering_FixedUpdate();
				break;
		}
	}
	
		private void FiniteStateMachine_LateUpdate()
	{
		switch (currentState)
		{
			case States.searchingForPlayer:
				WhileSearchingForPlayer_LateUpdate();
				break;
				
			case States.chasingPlayer:
				WhileChasingPlayer_LateUpdate();
				break;
				
			case States.attacking:
				WhileAttacking_LateUpdate();
				break;
				
			case States.recovering:
				WhileRecovering_LateUpdate();
				break;
		}
	}
	
	private void WhileSearchingForPlayer_NormalUpdate()
	{
		//Code
	}
	
	private void WhileSearchingForPlayer_FixedUpdate()
	{
		//Code
	}
	
	private void WhileSearchingForPlayer_LateUpdate()
	{
		//Code
	}
	
	private void WhileChasingPlayer_NormalUpdate()
	{
		//Code
	}
	
	private void WhileChasingPlayer_FixedUpdate()
	{
		//Code
	}
	
	private void WhileChasingPlayer_LateUpdate()
	{
		//Code
	}
	
	//And so on and so forth
}

As you can see, it very quickly becomes an ungodly amount of code for me to keep updated and organized.

So here’s my question: What is a smarter way for me to do this? Is there some clever way I can have a finite state machine that allows me to put different code in all three update methods for each state, without needing to write tons and tons of short methods? Is there any way I can keep all of the code for my states separated and organized?

I would suggest checking out the FSM tutorials on the Unity Gems website (or you might get lucky and the author ‘whydoidoit’ might chip in with some advice). The framework follows a similar design to your last example, but a bit more manageable. You define an enum with your states and create your state methods according to a naming convention. You would end up with something like –

public class SomeEnemy : StateMachineBehaviourEx 
{
   public enum State {
        Searching,
        Chasing,
    }
    
    private void Start() {
        currentState = State.Searching;
    }
    
    private void Searching_Update() {
        // code..
    }
    
    private void Searching_FixedUpdate() {
        // code..
    }
    
    private void Chasing_Update() {
        // code..
    }
    
    private void Chasing_FixedUpdate() {
        // code..
    }
}

…there is no need to create a ‘base’ Update or FixedUpdate functions, as the FSM framework handles that behind the scenes with delegates and reflection and will call and cache the appropriate Update method for the current state.