In C# unity my wait function is not waiting correctly

Viewed 172

I have recently learned coroutines in C# unity and I tried creating a wait function to wait in between codes. It prints both statements at the same time instead of waiting three seconds. Does anyone know a solution to this problem?

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

public class Learninghowtoprogram : MonoBehaviour
{
    private void Start()
    {
        print("hello"); 
        wait(3);
        print("hello2");      
    }

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

    void wait(float time)
    {
        StartCoroutine(waito(time));     
    }
}
3 Answers

The issue here is when Start() gets called it tries to execute each line one by one

print("hello"); 
wait(3);
print("hello2");

So when you are calling the wait(3) it goes in it's own scope and calls the waito Coroutine.

Now see the yield return new WaitForSeconds(time); is doing it's job correctly that means it's waiting for 3 seconds but in it's scope (inside itself) so what you can do is move print("hello"); and print("hello2"); in the Coroutine itself like this..

public class Learninghowtoprogram : MonoBehaviour
{
    private void Start()
    {
        wait(3);
    }

    void wait(float time)
    {
        StartCoroutine(waito(time));
    }

    IEnumerator waito(float time)
    {
        print("hello");
        yield return new WaitForSeconds(time);
        print("hello2");
    }
}

Or, you can remove wait() and directly start the Coroutine like this also

public class Learninghowtoprogram : MonoBehaviour
{
    private void Start()
    {
        StartCoroutine(waito(3));
    }

    IEnumerator waito(float time)
    {
        print("hello");
        yield return new WaitForSeconds(time);
        print("hello2");
    }
}

If you to stop time in function or wait to perform a task. Use Async.

private async void Start()
{
    print("hello");
    await Task.Delay(3000);
    print("hello2");
}

You can make Start a Coroutine by returning IEnumerator.

private IEnumerator Start() {
    Debug.Log("Start 1");
    yield return waito(3);
    Debug.Log("Start 2");
}
IEnumerator waito(float time) {
    yield return new WaitForSeconds(time);
}

Note the Timestamps:

Logs from delayed Start

But I think it's bad design. Awake is called before Start, Start is called before the first Update. And sometimes Unity devs rely on that order, to access References etc. By delaying the execution of Start you alter that order a bit.

So while the above works, I'd suggest to check a timer variable in Update or start a separate Coroutine in Start that runs later, but still letting Start return void.

Related