Using coroutines with a Finite State Machine help

I’m trying to create a simple Finite State Machine for the bosses within my game as I want them to have different attacks and randomly switch between them.

This is the script I’ve used for the Finite State Machine:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class FSM : MonoBehaviour {

	public delegate void State();
	private List<State> availableActions = new List<State>();
	private State action;

	public FSM(State state)
	{
		action = state;
	}

	public void AddState(State state)
	{
		availableActions.Add(state);
	}

	public void RandomState()
	{
		SetState(availableActions[Random.Range(0, availableActions.Count)]);
	}

	public void SetState(State state)
	{
		action = state;	
	}

	void Update () 
	{
		action();
	}
}

I simply add a method using the AddState() method within a boss class and it will be added to the availableActions list which will be looped through when calling RandomState(). Or I can just use SetState(). Currently it works fine but I’m having to remove one of the actions that my boss has because it’s a coroutine and of course I want to be able to use both types of methods (Voids and Corutines).

This is the error I get: http://i.imgur.com/MWkHeMO.jpg

I know it’s because of the coroutine but is there a way I can make my Finite State Machine work with coroutines also?

Thanks

Yes, the error message is pretty clear, you defined the delegate to return void, and your Fire method is a coroutine so it returns IEnumerator.

I guess you can do something like this:

public void Fire() {
    StartCoroutine(FireCoroutine());
}

IEnumerator FireCoroutine() {
    //your coroutine code
}

That way you have a method that matches the delegate and starts a coroutine, but you have to be carefull since the object with the Fire script attached will actually run the coroutine, so it must be an active object and the Fire method should be inside a MonoBehaviour derived class.

Instead of a solution, I would like to suggest an alternative approach. Using coroutines or FSMs can quickly become cumbersome for handling complex AI. Using a Behaviour Tree is more appropriate defining such AI. Have a look at Panda BT, which is a scripting framework based on Behaviour Tree.

To give you a preview of how simple it is to define AIs, the script for your Boss AI to randomly select and execute an action from a given set, would look something like this:

tree("DoRandomAction")
    random
        tree("Action1")
        tree("Action2")
        tree("Action3")

Of course, you can do much more that with Behaviour Tree. In fact, it is an handy tool to write any logic that runs over several frames.

I’m the author of Panda BT, so if you have any question about this tool, I’d be glad to help.