Coroutine without MonoBehaviour

Hello,

Is there a way to have a coroutine without deriving from MonoBehaviour and having an instantiated GameObject. For various reasons it is necessary that this class not be a game object and thus it can’t derive from monobehaviour, however I need it to be able to run coroutines. Does anyone know how to do this?

Thanks in advance

Just to share my solution in full, I use an absolute minimal number of monobehaviours, and instead I use one main one and then managed custom subcontrollers that get called through to. So in the non-monobehaviour class, define your IEnumerator like normal:

private IEnumerator DelayedMapTransition(MapPos mapTarget, MapController.ExitTypeEnum exitType, float preDelay)
	{
		//Debug.Log("Start delay " + preDelay.ToString());
		
		yield return new WaitForSeconds(preDelay);
		
		//Debug.Log("End delay " + preDelay.ToString());
		
		MapTransition(mapTarget, exitType);
	}

And then in your master monobehaviour, create an interface to call through to:

//To support external coroutines being called:
public void StartChildCoroutine(IEnumerator coroutineMethod)
{
    StartCoroutine(coroutineMethod);
}

And then finally the non-monobehavoiurs’ can coroutine to their little hearts content, eg:

public void MapTransitionDelayed(MapPos mapTarget, MapController.ExitTypeEnum exitType, float preDelay)
{
	SceneController.instance.StartChildCoroutine(DelayedMapTransition(mapTarget, exitType, preDelay));
}

Good solution above @jistyles, except you don’t need StartChildCoroutine( )

just use

SceneController.instance.StartCoroutine(YourCoroutine(args)){ }

Because its a MonoBehavior anyway. You don’t need this interface

you can do it a few different ways

one is using a singleton on a monobehaviour object
another is to create an instance of the class and pass it in that way.

public class Test
{
    private void RunCoroutine()
    {
        Test2.t.GetComponent<Test2>()._StartCoroutine(enumerator());
    }

    public IEnumerator enumerator()
    {
        yield return new WaitForSeconds(1);
    }
}

public class Test2 : MonoBehaviour
{
    public static GameObject t;

    private void Awake()
    {
        if (t != gameObject || !t)
            t = gameObject;
    }

    public void _StartCoroutine(IEnumerator iEnumerator)
    {            
        StartCoroutine(iEnumerator);
    }
    public void _StartCoroutine()
    {
        Test t = new Test();
        StartCoroutine(t.enumerator());
    }
}

Hi. Thank you @jistyles for your answer. I am conceiving a game the same way, with one main MonoBehaviour script, and other non MonoBehaviour scripts. I just don’t understand how you instantiate your main script. Thank you very much for your answer.
,Hi, I conceived my game the same way, with one main MonoBehaviour and other non MonoBehaviour Class. So I would like to use your solution. But I don’ understand how you instantiate your main MonoBehaviour Script.
Thank you very much for your answer

For some scenarios (when you have the editor available) you can use Unity’s own Editor Coroutines package

Keep in mind that it gets tricky if you have assembly definitions in the mix (this makes sense as an editor assembly which means that, depending on where you use it, you’d be forced to depend on it from a possible runtime assembly)

There is a free asset that allows you to do that without writing your own implementation: More Effective Coroutines

Besides, it allows you to run coroutines in disabled MonoBehaviours, and its coroutine implementation allocates less memory.