[Solved] - simple X seconds wait before launching your script ? (Beginner)

Hello

I wanted to create a simple X seconds pause before launching my script, so I tried to write this, but it’s obviously wrong, because nothing is launched anymore now. Can you explain me what I should have done please?
Thx

    private float startWait = 3;

// -------------------------------------------------------------------
    void Start()
    {
        float startCount = startWait- Time.time;
        if (startCount < 0f)        
        {
        // execute the rest of my my script

Edit: “better script logic”

so I tried this

        float sc = startWait;

        while (sc > 0f)
            {
            sc = startWait - Time.time;
        }

        if (sc <= 0f)
       {
       // execute the rest of my my script

But it make Unity freeze :(…
(probably stuck in the while loop, even if I don’t get why)

So now, i’m trying to go with a Coroutine

    private bool itIsTrue = false;
    
// -------------------------------------------------------------------
    void Start()
    {

        Debug.Log( itIsTrue );
        StartCoroutine ("Wait");

        if (itIsTrue)
        {
        // execute the rest of my my script

    IEnumerator Wait()
    {
        yield return new WaitForSeconds (startWait);
        itIsTrue = true;
    }

Can someone tell me why after the coroutine is placing the itIsTrue to true, thinga are not working ?
Thx

I haven’t got a lot of time right now, but regarding your first example, the Start() method is only executed once.
It’s likely the time has passed and not reached the desired time in Start.
Try moving it to the Update() method.

I think Gnatty is right about the Start function. As is it called only once, you probably never reach 0 in startWait. You should use Update()
In addition, I’m not 100% sure, but you should use Time.deltaTime, to decrease startWait the time it spent between each update

It’s simpler to use Invoke.

private float startWait = 3f;

void Start() {
    Invoke("Initialize", startWait);
}

void Initialize() {
    // Your code
}
1 Like

So this code:

        float sc = startWait;

        while (sc > 0f)
            {
            sc = startWait - Time.time;
        }

        if (sc <= 0f)
       {
       // execute the rest of my my script

Time.time doesn’t change during a frame, and it’s 0 on the first frame. So if that’s in start, your code is:

 while(sc > 0f) {
    sc = startWait - 0f;
}

Which is an infinite loop.

In this code:

    private bool itIsTrue = false;
   
// -------------------------------------------------------------------
    void Start()
    {

        Debug.Log( itIsTrue );
        StartCoroutine ("Wait");

        if (itIsTrue)
        {
        // execute the rest of my my script

    IEnumerator Wait()
    {
        yield return new WaitForSeconds (startWait);
        itIsTrue = true;
    }

The coroutine is started, but that doesn’t block the execution of Start from continuing - so the if(itIsTrue) check happens before the WaitForSeconds is finished running.

The coroutine is the correct way to go, but you don’t need an itIsTrue bool - just stick the code you want to run after some seconds in the Coroutine:

    void Start()
    {
        StartCoroutine (Wait());
    }

    IEnumerator Wait()
    {
        yield return new WaitForSeconds (startWait);
        // execute the rest of your script
    }

As an added bonus, if you turn Start into an IEnumerator, Unity will run it as a coroutine for you. You can’t really do this with any other methods, but for your use case, this is perfect:

IEnumerator Start() {
    yield return new WaitForSeconds(startWait);
    //run code
}
2 Likes

Thx Everyone,
I took a break after being very frustrated spending so much time understanding this :)…
and now i’m ready to read all this and get it done !

I guessed that my code was not called anymore because it was in a “Start”
but the problem is that the code was not meant to be in a void Update, because it should not be repeated! :slight_smile:

Thx again !

Hey Baste

Thx for your time and explantations.
I used your 1st method, because I don’t get yet why i should transform my Start in IEnumerator, and who knows, maybe i’ll need some other stuff later in my start.

So, it’s working, but I have two extra question
My code is calling a Coroutine, and it’s now called from the Coroutine Wait()… is it alright to do so ?
and should I write at the end of if a StopCoroutine(“Wait”);

    void Start()
    {
        StartCoroutine (Wait());
    }

    IEnumerator Wait()
    {
        yield return new WaitForSeconds (startWait);
        // execute the rest of your script

        StartCoroutine ("SpawnLoop");
        StopCoroutine("Wait");
    }

Thx.

The reason you may want to turn Start into an IEnumerator is because then you can use yield return WaitForSeconds(time) before the rest of the coroutine is executed, thus pausing the execution of your script.
Alternatively, you could use Invoke and not have to deal with coroutines and WaitForSeconds, like this

int waitTime;
void Start()
{
   Invoke("function", waitTime);
   //This will execute function 'function' after waiting waitTime in seconds, unless designated otherwise
}

void function()
{
   //do stuff, like calling or invoking other functions
}

Personally, I don’t much like coroutines, but they do have their uses.

You could use your script as you have posted, but rather than using

StopCoroutine("Wait");

you could just use

yield break;
2 Likes

if you want to pause it, you would have to set enabled to false in the start of your Start method than return it to true after the coroutine has run.

even know you have paused Start with the courutine Update will still run like normal unless enabled = false

Thx a lot for all these comments and help.

I don’t have yet the skills or knowledge to think about “Pausing” my game yet. I will have first to move to simple task like launching the game again after the death of the player and being able to start the level from scratch.

I’m learning by doing a “flappy bird” type of game, I don’t look for being original here, just learning by myself to do a 2d prototype in unity (i’m originally an animator, so scripting C# si far from my orignal skills ;).

So thx again for the help and comments, my protoype is moving forward, it’s always rewarding :).

No. The coroutine is finished, there is no need to stop it. Your StopCoroutine call does exactly nothing.

yield break in the end of an IEnumerator is like an empty return statement in the end of a void method. No point.

I see, so I can instead use StopCoroutine to stop another one,
like when a character is dead, stop spawning stuffs that are in a coRoutine dedicated to spawn (this is just an example).

    public void StopSpawn()
    {
        StopCoroutine("SpawnLoop");         //stops another Coroutine spawning function
    }

Pretty much, yes.

Hi, you might want to check out another solution to make delays

We were frustrated with writing coroutines, and the only simple, one-line, solution was to use Invoke, but it cannot delay methods with parameters, so we created a tool that allows you to have more control on delays and at the same time it is easy to use.

Your code would be:

private float waitTime = 3f;

void Start() {
    SuperInvoke.Run(waitTime, YourMethod);
}

private void YourMethod() {
    // code of your script
}