Problem with WaitForSeconds() inside a Coroutine(), it just doesn't wait

Hello,

I’m trying to figure out how WaitForSeconds works inside a coroutine. As I understand it just delays a fixed amount of seconds the return of a coroutine. So to test it, I wrote a very basic script:

protected  void Start ()
    {   

        MoveItMoveIt();
    }

protected void MoveItMoveIt()
    {
        for(int i = 0; i < 5; i++)
        {
            Debug.Log ("Going to Coroutine", gameObject);

            StartCoroutine(ColdDown());

            Debug.Log ("Coming back from Coroutine", gameObject);
        }
    }

private IEnumerator ColdDown()
    {
        yield return new WaitForSeconds(2.0f);
    }

I was expecting to watch the console display the “Coming back from Courutine” message 2 seconds later than “Going to Coroutine”, but instead the console display inmediately the 10 messages of the for loop.

Can anyone tell me what am I doing wrong? Thank you for your feedback.

Just add: I’m working with C# and the gameObject that contents this script is instantiated by a gameManager as soon as the “game” starts.

1 Like

Put the loop and your debug messages inside the coroutine.

The way it’s currently set up, you’re telling this behaviour to start 5 coroutines all at once, that simple wait for 2 seconds, and then do nothing.

2 Likes

You’re just starting the coroutine, not yielding on it. Note that there’s no reason to even have a coroutine that only has WaitForSeconds, just replace the coroutine call with WaitForSeconds.

–Eric

1 Like

Thanks for your reply. I understand what you mean.

So my goal was to call the coroutine 5 times, with a 2 second delay between each call. I though the coroutine was like a thread and the yield was some kind of sleep (I’m still very noob :face_with_spiral_eyes:). I will try once again using flags, and post the results.

Thanks for the feedback Eric, I tried what I think you said, but it is still not dealy between messages in the console. Just all of them appear together at the beggining.

protected override void Start ()
    {
        MoveItMoveIt();
    }
     

protected void MoveItMoveIt()
    {
        for(int i = 0; i < 5; i++)
        {
            Debug.Log ("Going to Courutine", gameObject);
            new WaitForSeconds(3.5f);
            Debug.Log ("Comming back from Courutine", gameObject);
        }
    }

–Eric

Ok, I got what I wanted. Thank you very much for your comments guys.

My final goal was to make a gameObject move every X seconds, for example an enemy. Changing the delay of WaitForSeconds I make it move faster or slower depenging on the type of enemy. So here it is what I wrote:

private void Start ()
     {
        StartCoroutine(ColdDown());

     }

private void MovingThings()
    {
        Debug.Log ("Moving Enemy", gameObject);
    }

    private IEnumerator ColdDown()
    {
        //Assuming the enemy is always moving
        for(;;)
        {
            //Moving every 1.5 seconds
            yield return new WaitForSeconds(1.5f);
            MovingThings();
        }

    }

Hope it can help you

using System;

public void YourFunc()
    {
           StartCoroutine(DelayFunc(()=>
            {
                for(int i = 0; i < 5; i++)
                {
                   Debug.Log("HI");
                }
            }, 1.0f));
    }


    IEnumerator DelayFunc(Action func, float delay)
    {
        yield return new WaitForSeconds(delay);
        func();
    }

That won’t work at all; the OP already posted working code (that’s much more straightforward).

–Eric

What do u mean of won’t work at all?
because it works on me?
it will print hi * 5 after 1 seconsd

what is the problem?
ps: just want to learn more things

edit: i guess what you mean is it isn’t print 5 times each with a delay 1 secs
my bad that i didn’t read through his post, sry