My Coroutine Ignores the Boolean
In another script, a bool controls when this coroutine starts and stops:
IEnumerator SpawnWaves ()
{
if (SceneManager.GetActiveScene().buildIndex == 7)
{
shrinkStage = true;
}
if (shrinkStage == false)
{
yield return new WaitForSeconds(startWait);
while (true)
{
for (int i = 0; i < hazardCount; i++, fireCometCount++)
{
//var asteroidY = Random.Range (Mathf.RoundToInt(-spawnValues.y), Mathf.RoundToInt(spawnValues.y));
//var collectY = Random.Range (Mathf.RoundToInt(-spawnValues.y), Mathf.RoundToInt(spawnValues.y));
var random = Random.Range(0, 3) + 1;
//Debug.Log (Mathf.RoundToInt(-spawnValues.y) + " - " + Mathf.RoundToInt(spawnValues.y));
//if (asteroidY == collectY) {
if (random == 1)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(hazard, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnWait);
}
else if (random == 2)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(collectable, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnWait);
}
if (fireCometCount == 20)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(comet, spawnPosition, spawnRotation);
fireCometCount = 0;
yield return new WaitForSeconds(spawnWait);
}
}
yield return new WaitForSeconds(waveWait);
if (gameOver)
{
restartText.text = "Restart";
restart = true;
//break;
}
}
}
}
But in another script this bool is completely ignored:
IEnumerator SpawnShrinkWaves()
{
if (gameController.waveTransition == false)
{
while (true)
{
for (int i = 0; i < hazardShrinkCount; i++)
{
var random = Random.Range(0, 12) + 1;
if (random == 1 || random == 2 || random == 3 || random == 4)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(hazard, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
else if (random == 5 || random == 6 || random == 7 || random == 8)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(collectable, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
else if (random == 9 || random == 10)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(shrinkHazardOne, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
else if (random == 11 || random == 12)
{
Vector3 spawnPosition = new Vector3(11, -0.2f, -2);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(hazardBarrier, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
}
}
}
}
I know it's not the bool itself, because this works in the same script:
void SpawnBarrier()
{
if (gameController.waveTransition == false)
{
Vector3 spawnPosition = new Vector3(11, -0.2f, -2);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(hazardBarrier, spawnPosition, spawnRotation);
}
}
So why does the Coroutine ignore the bool? Why doesn't the loop only start when waveTransition == false? I want my Coroutine to play, and stop during the wave transition, then play again. By the way, I've never got StopCoroutine to work. I've always stopped coroutines with a boolean, which has worked until now! I can't figure out what's different. If anyone could help me that would be much appreciated.
$$anonymous$$aybe hazardShrinkCount is at zero which is skipping the for loop? Can you give a bit more of a rundown on what you want happening in your script, it's kind of difficult to abstract what is intended to happen.
Hey, thanks for your reply. The hazardShrinkCount is set to 30, just like in the first code above. Essentially, the SpawnWaves coroutine (the first code sample) is controlled by a bool, which is always false, until I enter a different scene, which I tell it to make that bool true. And this works (I should tell you this script is DontDestroyOnLoad, too).
But in my second code sample, the bool 'gameController.waveTransition == false' is ignored. I have tested it in the game editor and I've found when the waveTransition bool turns to true, the while loop still plays. All I'm doing to start the coroutine is using Void Start and then StartCoroutine(SpawnShrinkWaves()).
So all I want is the SpawnShrinkWaves coroutine to be controlled by a bool. I want that coroutine to start when the bool is false, and stop when the bool is true. Do you know of another method of doing this? The first sample code is an example of how I've got it to work before, I just can't figure out why it doesn't this time. Is it perhaps to do with the WaitforSeconds lines of code that don't exist in the SpawnShrinkWaves coroutine?
How are you calling the coroutine?
If it were me I would call it in Update() like this.
if (gameController.waveTransition == false)
StartCoroutine ("SpawnShrinkWaves");
and would change the Coroutine to this
IEnumerator SpawnShrinkWaves()
{
for (int i = 0; i < hazardShrinkCount; i++)
{
var random = Random.Range(0, 12) + 1;
if (random == 1 || random == 2 || random == 3 || random == 4)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(hazard, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
else if (random == 5 || random == 6 || random == 7 || random == 8)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(collectable, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
else if (random == 9 || random == 10)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(shrinkHazardOne, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
else if (random == 11 || random == 12)
{
Vector3 spawnPosition = new Vector3(11, -0.2f, -2);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(hazardBarrier, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
}
But I am not sure when your waveTransition is set to true, otherwise Update will continuously call the coroutine, or you need to make a second bool for when the coroutine is active e.g
if (gameController.waveTransition == false && shrinkWaveRoutineRunning == false) StartCoroutine ("SpawnShrinkWaves");
then you just set the shrinkWaveRoutineRunning bool to true at the start of the coroutine, and back to false when the coroutine is resolved.
by your design, that only gets checked once, at the start of that routine. Are you certain you didn't intend to do:
while (true)
{
if (gameController.waveTransition == false)
{
//...
}
}
ins$$anonymous$$d of the existing:
if (gameController.waveTransition == false)
{
while (true)
{
//...
}
}
Yeah I've tried that and it hasn't worked. Even with an If statement that checks true then break;
Even making it while(wave.transition == false) hasn't worked
So I've made a mistake when I told you that the first code sample works - that is also actually ignoring the bool. As far as I'm aware, I can't get bools to start/stop a coroutine; it's not happening for me.
Has anyone been able to successfully control when a coroutine will pause/play using a bool, or any other method? It's very rare that it takes this long to find the answer to my solution, as I've usually solved it by now! So if anyone could help point me in the right direction, I would very much appreciated. $$anonymous$$eanwhile I'll keep plugging away to try and figure it out!
In the past, I've 'paused' coroutines by making the WaitForSeconds 0, because I've used them to spawn objects. Obviously this looks like the coroutine is paused, but it isn't really. Is that, unfortunately, how I have to have it?
Answer by Xenocide · Nov 22, 2016 at 01:23 AM
OK, so I've achieved my goal by changing the code to this:
IEnumerator SpawnShrinkWaves()
{
for (int i = 0; i < hazardShrinkCount; i++)
{
var random = Random.Range(0, 12) + 1;
if (random == 1 || random == 2 || random == 3 || random == 4)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(hazard, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
else if (random == 5 || random == 6 || random == 7 || random == 8)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(collectable, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
else if (random == 9 || random == 10)
{
Vector3 spawnPosition = new Vector3(spawnValues.x, Random.Range(-spawnValues.y, spawnValues.y), spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(shrinkHazardOne, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
else if (random == 11 || random == 12)
{
Vector3 spawnPosition = new Vector3(11, -0.2f, -2);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(hazardBarrier, spawnPosition, spawnRotation);
yield return new WaitForSeconds(spawnTime);
}
if (gameController.waveTransition == true)
{
hazardShrinkCount = 0;
yield return new WaitForSeconds(10f);
hazardShrinkCount = 30;
}
}
}
By adding the bool within the loop and checking for waveTransition == true, I've made the hazardShrinkCount = 0 so that nothing spawns. This lasts for 10 seconds (the length of inactivity during the wave transition), and then hazardShrinkCount returns to 30 to continue spawning as the new wave begins.
Now, this means the coroutine doesn't actually pause, it just appears so when playing the game. It's not exactly what I want but at least it works.
My question still stands, though. How do you pause/play a coroutine using a bool? If this is impossible, how do you pause/play a coroutine at all? And if THAT is impossible, why can't you pause/unpause a coroutine? As far as I'm aware, you can only break (stop coroutine) and then can never start it again.
Your answer
Follow this Question
Related Questions
Rotate while Boolean=true 0 Answers
Coroutine with multiple Loops 2 Answers
Destroy Problem 2 Answers
Local bool won't change inside coroutine 1 Answer
Help with coroutine crashing unity 1 Answer