Just a quick question about yield in function Update

Hello guys, I have an Update function. I have a small piece of code in it:

void Update(){
    if (sargaKocka.GetComponent<Kocka>().getBennevan())
    {
            StartCoroutine(Wait(3));
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
    }
}

So IF my statement is TRUE, I need to wait for seconds, and after this I’d like to change scene.

public IEnumerator Wait(float time)
    {
        yield return new WaitForSeconds(time);
    }

But it seems it doesn’t really want to work. What am I doing wrong? How should I do this?

Only code within a Coroutine will wait before executing due to ‘yield’. The coroutine will start, but the next line in Update will execute in the same frame.

This is how I usually make reusable coroutines:

// i have this declared in a high-level class of useful things
// (or you can declare it in this class if its the only place needing callbacks)
public delegate void Callback();

void Update() {
    if(sargaKocka.GetComponent<Kocka>().getBennevan()) {
        // here the delegate is a block of code passed into the "wait" function
        StartCoroutine(Wait(3, delegate () {
            // wont be executed until the Wait coroutine calls "callback()"
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
        }));
    }
}

// wait gets an extra optional parameter "callback"
public IEnumerator Wait(float time, Callback callback = null) {
    yield return new WaitForSeconds(time);
    if(callback != null) {
        callback();
    }
}

Alternatively you can create two coroutines to do this (arguably less ugly, but less versatile):

void Update() {
    if(sargaKocka.GetComponent<Kocka>().getBennevan()) {
        StartCoroutine(LoadNextScene());
    }
}

public IEnumerator LoadNextScene() {
    yield return Wait(3); // at this point you may as well just use "new WaitForSeconds"
    SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}

public IEnumerator Wait(float time) {
    yield return new WaitForSeconds(time);
}
2 Likes

You could also use Invoke(“methodName”, 3f);
The downside to invoke is you can’t pass it parameters.

1 Like

Thank you for the quick response, it works. I keep it in my mind!

1 Like