A Catch 22 with MonoBehaviour?

I am trying to make a monobehaviour class to be able to run coroutines which can not be started from non-monobehaviour classes, as suggested in this blog post:

It sounds great until I try to instantiate the monobehaviour class that I made so that I can use it. But I’m not allowed to “new” a monobehaviour class.

Any help would be greatly appreciated!

This is what I have:

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

public class CoroutineCentral : MonoBehaviour {
public delegate IEnumerator CoroutineMethod();

IEnumerator runCoroutine(CoroutineMethod coroutineMethod) {
return coroutineMethod();
}

public Coroutine startCoroutine(CoroutineMethod coroutineMethod) {
return StartCoroutine(“executeCoroutine”,coroutineMethod);
}
}

And this is where it fails when I try to use it from another non-monobehaviour class:

CoroutineCentral cs = new CoroutineCentral(); // NOT ALLOWED
CoroutineCentral.CoroutineMethod cm = Download;
cs.startCoroutine( cm );

I prefer to set that up as a lazy singleton:

public class CoroutineCentral : MonoBehaviour {
    private static CoroutineCentral _instance;
    private static CoroutineCentral instance {
        get {
            if(_instance == null) {
                _instance = new GameObject("[Coroutine Central Container]").AddComponent<CoroutineCentral>();
            }
            return _instance;
        }
    }

    public static Coroutine StartRoutine(IEnumerator coroutine) {
        return instance.StartCoroutine(coroutine);
    }
}

//usage, in some other MonoBehaviour:

private void StartCountDownAndDestroySelf() {
    CoroutineCentral.StartRoutine(CountDown());
    Destroy(gameObject);
}

private IEnumerator CountDown() {
    for(int i = 0; i < 10; i++) {
        Debug.Log(i);
        yield return new WaitForSeconds(1f);
    }
}

I find it’s much better to expose static methods and hide the singleton as a private static variable, than to expose the instance and call instance methods on it.

3 Likes

@Baste This is fantastic, thank you so much! You made my day and saved me hours of headscratching.