Can I use coroutines to wait for a collection of other coroutine-enabled methods to complete?

I have something like this:

foreach (TBHoming homing in homingObjects) {
    StartCoroutine(homing.MoveHomeOverTime());
}

Inside the MoveHomeOverTime method, a loop moves each object toward a predetermined position, yielding after each small step, until it reaches its “home” spot. So far, so good.

Now what I’d like to do is to be able to notice at this point in the code when all of those coroutines have completed, that is, when each of them stops yielding anything and finally just returns. Each of these objects can have a different distance to move, so I don’t really hardcode a time. Any ideas? I’m guessing that this may not be easily doable without something like a true “await”, but I’d be happy to be proven wrong!


PS: I realized while typing that I can work around this by precalculating the amount of time each object will need to move, remember the highest, and then just wait that amount of time. So I have a solution for my real-world problem, but am still curious to see if there exists a general way to wait for a collection of coroutines to complete.

1 Answer

1

The math behind this type of stuff is Semaphores and Mutexes, from Operating Systems theory.

Could make a counter numWaitingOn set equal to the number of homing objects you have. When each MoveOverTime finishes, subtract one. The main loops yields until the count hits zero.

To avoid polluting moveOverTime, could have the original foreach instead call helpers like this:

IEnumerator moveAndWait(TBHoming tbh) {
  yield return StartCoroutine(homing.MoveHomeOverTime());
  numWaitingOn--;
  // this is iffy, avoids the "yield each frame" loop, but harder to read:
  if(numWaitingOn<=0) doFinalStuff();
}