Pausing script execution until a specific event in another script
I'm trying to come up with a way to pause a script execution until certain conditions are met on another script. Here's the code that I want to pause until that certain event and continue after it is completed.
void CalculateTurnOrder () {
units = GameObject.FindGameObjectsWithTag ("Unit").OrderByDescending(go => go.GetComponent<Stats>().speed).ToArray();
for (int i = 0; i < units.Length; i++) {
if (i+1 < units.Length) {
if (units [i].GetComponent<Stats> ().friendFoe == "Friendly") {
units [i].GetComponent<PlayerMoveUnit> ().SelectUnit ();
}
if (units [i].GetComponent<Stats> ().speed - units [i+1].GetComponent<Stats> ().speed >= units [i+1].GetComponent<Stats> ().speed) {
i--;
}
}
}
}
The idea is that each unit has a Speed stat, which determines their turn order. What I need is for the iteration, the script itself maybe to stop until the unit, the GameObject you call SelectUnit() on, completes whatever actions it can. THEN the script resumes and most likely gives the next unit in line a move (or move twice if the speed of the i unit is at least twice as big as the i+1 unit).
So how do I make this script wait for a condition like
(!units[i].GetComponent<PlayerMoveUnit> ().IsSelected)
One way is a coroutine. Can make a loop with that skips frames until whenever. But that only works if each units runs itself. This runs all at once? Could rewrite -- just have the loop skip units if it's not their turn.
Answer by Laurgrin · Mar 09, 2016 at 05:38 PM
After some digging and not very helpful Unity documentation about WaitUntil, I've accomplished it by adding a few yield lines and turning it into coroutine.
IEnumerator CalculateTurnOrder () {
units = GameObject.FindGameObjectsWithTag ("Unit").OrderByDescending(go => go.GetComponent<Stats>().speed).ToArray();
for (int i = 0; i < units.Length; i++) {
if (i+1 < units.Length) {
if (units [i].GetComponent<Stats> ().friendFoe == "Friendly") {
units [i].GetComponent<PlayerMoveUnit> ().SelectUnit ();
yield return new WaitUntil (() => !units [i].GetComponent<PlayerMoveUnit> ().IsSelected);
yield return new WaitForSeconds (1);
}
if (units [i].GetComponent<Stats> ().speed - units [i+1].GetComponent<Stats> ().speed >= units [i+1].GetComponent<Stats> ().speed) {
i--;
}
}
}
}
To anyone else stumbling upon this issue, WaitUntil has some wierd syntax, namely yield return new WaitUntil(() => condition)
. That honestly should be in the documentation, or I'm just a really green coder for not knowing this specific syntax. Other than that, this issue is solved.