While Loop Not Running When Set True in Code, But Will Run If Set Manually In Unity

Hello All,

I have the following problem with the below script. I have a powerup in my game called Freeze that is freezing the spawning of enemies by setting a boolean spawnActive variable in another script to false which stops them spawning. This part is working exactly how i want it to, however in the below script the while loop should run when freezeActive is set to true which i am doing in OnMouseDown(), so when a player clicks the freeze power up the loop should run.

This will not work when set in this way, if i write in at the top public bool freezeActive = true instead of false this will work. Also if I click the freezeActive variable on inside Unity manually it will work.

I can even see the freezeActive variable being ticked on in unity when I click the power up, but the loop will not run.

Any assistance would be greatly appreciated :slight_smile:

Have a great xmas!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class freeze : MonoBehaviour {

    public bool freezeActive = false;

    //starting timer for freezeTime
    void Start()
    {
        StartCoroutine (freezeTime());
        Debug.Log ("timer Started");
    }

    //find the spawnActive and stop it, set clicked to true
    void OnMouseDown()
    {
        FindObjectOfType<spawner>().spawnActive = false;
        FindObjectOfType<powerUpSFX>().playPowerUpSFX();
        freezeActive = true;
    }
       
    //clicked is set to true so the loop runs, it should wait 5 seconds and then set spawn active back on
    IEnumerator freezeTime()
    {
        while (freezeActive)
        {
            yield return new WaitForSeconds(5);
            FindObjectOfType<spawner>().spawnActive = true;
            freezeActive = false;
        }
    }

    // Update is called once per frame
    void Update () {
        transform.Rotate(new Vector3 (1, 1, 0));
    }
}

when your script starts, it starts the coroutine, and because freezeTime is set to false, it immediately drops the coroutine.

The simple fix is like so:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class freeze : MonoBehaviour {
 
    public bool freezeActive = false;
 
    //starting timer for freezeTime
    void Start()
    {
        StartCoroutine (freezeTime());
        Debug.Log ("timer Started");
    }
 
    //find the spawnActive and stop it, set clicked to true
    void OnMouseDown()
    {
        FindObjectOfType<powerUpSFX>().playPowerUpSFX();
        freezeActive = true;
    }
       
    //clicked is set to true so the loop runs, it should wait 5 seconds and then set spawn active back on
    IEnumerator freezeTime()
    {
        while (true)
        {
            if(freezeTime){
				FindObjectOfType<spawner>().spawnActive = false;
				yield return new WaitForSeconds(5);
				FindObjectOfType<spawner>().spawnActive = true;
				freezeActive = false;
			} else {
				yield return null;
			}
        }
    }
 
    // Update is called once per frame
    void Update () {
        transform.Rotate(new Vector3 (1, 1, 0));
    }
}
2 Likes

You sir, are a genius!

Thank you kindly!

Merry Christmas