RnRoger
RnRoger

Reputation: 690

Unity: Wait() in Update almost working (But not quite)

I have a code (C#) with an update function that needs to wait for a few seconds at some point. The problem is that while it is executing the wait command it continues down the update function, resulting in the bit that is supposed to be delayed, to be completely skipped. Because of the boolean variables the update will only do this stuff once, until I make it available again, so that is no problem. The code works without the whole waiting thing so don't worry about that, I left out most lines that don't have to do with waiting anyways.

void Update()
{

    if (RoundOver == false)
    {
        RoundOver = true;
        Seconds = 3;
        Debug.Log("Waiting", gameObject);
        StartCoroutine(Wait());
        if (Continue)
        {
            Continue = false;
            Debug.Log("Done Waiting", gameObject);
            RoundNumber += 1;                //Just game stuff
            ZombiesLeft = ZombieAmount();    //Just game stuff
            RoundOver = false;
        }
        Debug.Log("Done wit stuff", gameObject);
    }
    if (counter > DelayTime && RoundOver == false)
    {
        counter = 0;
        Debug.Log("Going to spawn a zombie", gameObject);
        SpawnZombie();
    }
    counter += Time.deltaTime;
    }

with les wait function:

IEnumerator Wait()
{
    Debug.Log("ACTUALLY WAITING", gameObject);
    yield return new WaitForSeconds(Seconds);
    Continue = true;
    Debug.Log("ACTUALLY WAITING DONE", gameObject);
}

The output is as follows:

Waiting
ACTUALLY WAITING
Done wit stuff
ACTUALLY WAITING DONE

So obviously the right order should be

Waiting
ACTUALLY WAITING
ACTUALLY WAITING DONE
Done wit stuff

EDIT: The block in if (continue) is supposed to activate the second block when the (here hidden) requirements are met. The second block would keep doing its thing until it is done (could take minutes) and then by setting RoundOver to false again re-enabling the first block. The first block is essentially to keep rerunning the second block with increasing variables like RoundNumber +=1, and, which is the only problem here, to have the second blocks separated by 3 seconds.

Upvotes: 1

Views: 2256

Answers (3)

RnRoger
RnRoger

Reputation: 690

I worked around this by turning the void SpawnZombie() into an IEnumerator instead of having the separate Wait(). I then replaced SpawnZombie() with StartCoroutine(SpawnZombie()). To make it act like I want it to I added an if in the SpawnZombie() to make sure the waiting of 3 seconds only occurred when I want it to.

Upvotes: 1

Juan Bayona Beriso
Juan Bayona Beriso

Reputation: 727

You cannot wait in the Update function, you can only wait in a function that returns an IEnumerator.

For this you can make something like this

void Update()
{
   if (RoundOver == false)
   {
        RoundOver = true;
        StartCoroutine(Wait());
   }
   if (counter > DelayTime && RoundOver == false)
   {
    counter = 0;
    Debug.Log("Going to spawn a zombie", gameObject);
    SpawnZombie();
   }
   counter += Time.deltaTime;
}

IEnumerator Wait()
{
    Seconds = 3;
    Debug.Log("Waiting", gameObject);
    Debug.Log("ACTUALLY WAITING", gameObject);
    yield return new WaitForSeconds(Seconds);
    Debug.Log("Done Waiting", gameObject);
    RoundNumber += 1;                //Just game stuff
    ZombiesLeft = ZombieAmount();    //Just game stuff
    RoundOver = false;
    Debug.Log("ACTUALLY WAITING DONE", gameObject);
    Debug.Log("Done wit stuff", gameObject);
}

Although this isn't the cleanest of the stuffs, I would remove if possible all the code from Update and start a coroutine when you need.

Upvotes: 3

code11
code11

Reputation: 2309

Your debug statement Debug.Log("Done wit stuff", gameObject); is outside of the if statement if (Continue). Because of this, it will display even if the coroutine is still running.

Upvotes: 0

Related Questions