If you're using Unity 2018.3 or newer, check out Unity AsyncRoutines which accomplishes the same thing, but uses C# 7's async/await for cleaner and more type-safe syntax.
Routines is a replacement for Unity's coroutines that provides hierarchical support. This means that a running routine can yield on one or more child routines and resume when they complete. Routines also utilize pooling under the hood to reduce garbage generation as much as possible so that they can used extensively without dropping frames.
Normally, you want to use a RoutineManager component to manage routines on a GameObject. This will handle all of the details of a routine's lifetime, including stopping it if the object is destroyed.
public class MyBehavior : MonoBehaviour{ public RoutineManager routineMgr; public void Start() { routineMgr = gameObject.AddComponent<RoutineManager>(); routineMgr.RunRoutine(MainRoutine()); } public IEnumerator MainRoutine() { for (var i = 0; i < 5; ++i) { yield return ChildRoutine(i); var result = Routine.GetResult<int>(); Debug.Log(result); } } public IEnumerator ChildRoutine(int i) { yield return routineMgr.WaitForSeconds(1); Routine.SetResult(i * 2); }}
Here we add a RoutineManager and run a simple routine that loops from 0 to 4. It then calls a child which waits for a second and returns the number multiplied by 2, which is received by the parent and sent to the console.
Protip: You can also directly derive your behavior from RoutineManager to get routine support built in to your component.
DoAllTheThingsInOrder() yields an array (it could be any IEnumerable) which causes the system to execute them in sequence - waiting for each child to finish before starting the next. The result will be whatever the last child set as a result.
DoAllTheThingsAtOnce() uses Routine.All() to specify a set of children which should be executed in parallel. The parent routine will resume once all children have finished and the result will be a List