public static class CoroutineManager
{
private static Mono _mono;
private static Mono Mono => EnsureMonoExists();
private static Mono EnsureMonoExists()
{
if(_mono != null)
return _mono;
var obj = new GameObject("CoroutineManager");
_mono = obj.AddComponent<Mono>();
UnityEngine.Object.DontDestroyOnLoad(obj);
}
public static void StartInSequence<T>(T[] objects, Func<T, IEnumerator> routineGetter, float delay = 0, Action onComplete = null)
{
Mono.StartRoutine(InSequence(objects, routineGetter, delay), onComplete);
}
private static IEnumerator InSequence<T>(T[] objects, Func<T, IEnumerator> routineGetter, float delay)
{
WaitForSeconds wait = null;
if(delay > 0)
wait = new WaitForSeconds(delay);
var running = 0;
foreach(var obj in objects)
{
running++;
_mono.StartRoutine(routineGetter.Invoke(obj), () => running--);
if(delay > 0)
yield return wait;
}
while(running > 0)
yield return null;
}
private class Mono : MonoBehaviour
{
public void StartRoutine(IEnumerator routine, Action callback = null)
{
StartCoroutine(Routine(routine, callback));
}
public IEnumerator Routine(IEnumerator routine, Action callback)
{
yield return StartCoroutine(routine);
callback?.Invoke();
}
}
}