To solve this problem, I had to break it down into two parts. First is the calling of Coroutines through a Static Method. Unity does not allow Coroutines to be called by default, but a class can be created to emulate this behaviour. The "StaticCoroutine" class allows the user to fire Coroutines in static methods with an internally stored, privately managed instance. The script requires no scene dependencies, so no need to add the monobehaviour script to a GameObject (unless you want to). To use, simply create a C# Script named "StaticCoroutine" and paste the following code in the script:
using System.Collections;
using UnityEngine;
public class StaticCoroutine : MonoBehaviour {
private static StaticCoroutine m_instance;
// OnDestroy is called when the MonoBehaviour will be destroyed.
// Coroutines are not stopped when a MonoBehaviour is disabled, but only when it is definitely destroyed.
private void OnDestroy()
{ m_instance.StopAllCoroutines(); }
// OnApplicationQuit is called on all game objects before the application is closed.
// In the editor it is called when the user stops playmode.
private void OnApplicationQuit()
{ m_instance.StopAllCoroutines(); }
// Build will attempt to retrieve the class-wide instance, returning it when available.
// If no instance exists, attempt to find another StaticCoroutine that exists.
// If no StaticCoroutines are present, create a dedicated StaticCoroutine object.
private static StaticCoroutine Build() {
if (m_instance != null)
{ return m_instance; }
m_instance = (StaticCoroutine)FindObjectOfType(typeof(StaticCoroutine));
if (m_instance != null)
{ return m_instance; }
GameObject instanceObject = new GameObject("StaticCoroutine");
instanceObject.AddComponent<StaticCoroutine>();
m_instance = instanceObject.GetComponent<StaticCoroutine>();
if (m_instance != null)
{ return m_instance; }
Debug.LogError("Build did not generate a replacement instance. Method Failed!");
return null;
}
// Overloaded Static Coroutine Methods which use Unity's default Coroutines.
// Polymorphism applied for best compatibility with the standard engine.
public static void Start(string methodName)
{ Build().StartCoroutine(methodName); }
public static void Start(string methodName, object value)
{ Build().StartCoroutine(methodName, value); }
public static void Start(IEnumerator routine)
{ Build().StartCoroutine(routine); }
}
I preferred this method over using Awake because I only query the instance whenever I need it. Whenever I don't have an actively-loaded instance, I can find another one (should it exist), or even dynamically create a blank GameObject with the needed script. This is why no scene alterations are needed, and that the code is simply plug and play.
The second part of the question is loading levels via Static Coroutines. Keep in mind that Application.LoadLevel is considered an Obsolete method, and was replaced with Unity's SceneManager. In this case, the simplest level change can be accomplished as follows:
SceneManager.LoadScene("SceneNameHere", LoadSceneMode.Single);
which will replace the currently loaded level with the new one. Indices won't work for this, so you'll need the scene name to make the transition. A preferred method is to use LoadSceneAsync() to avoid pauses or performance hiccups while loading. The Scripting Page for this method has an implementation which uses IEnumerator, which is completely compatible with both your code, as well as StaticCoroutine.