Coroutines and Scene Loader

Hi, i noticed that when i use a coroutine for WaitForSeconds, if i put the scene loader function outside the coroutine the delay doesn’t work, with other pieces of codes this does not occur, why is that? it’s like it has a priority over the coroutine(?)

This Doesn’t work as intended

this does work:


in other functions i created for implementing some aspects with coroutines for waiting this kind of behavior never occured

Hi Shinos,

The LoadGameOver method is a normal method. This means that it does not wait until the StartCoroutine method returns something. It executes the StartCoroutine method, the program jumps into the WaitAndLoad method, gets to the line with WaitForSeconds and immediately jumps back to LoadGameOver to executed the rest of the code block. That’s the difference between a method and a coroutine method: only the latter can “pause” and execute its code block with delays.

Is this what you wanted to know?

See also:

yeah but in other pieces of codes i only did a Coroutine with a yield return new WaitForSeconds(2) for example, and the delay worked even out the coroutine, here the delay works only if the scenemanager.loadscene is in the coroutine

Like here where i used only the piece of the coroutine as a “delayer” , here it works and it waits but with the scene manager functions it doesn’t wait the seconds i put before loading, unless i put the function in the coroutine brackets, while here in the example underneath is optional, it still works

How did you test that? With a Debug.Log and Time.frameCount or Time.time?

well i know for sure it works cause if i put 10 seconds it waits for it before the background starts scrolling

it’s not good to have a coroutine which only yields?

I’m a bit surprised that the Start method waits because of the coroutine. That actually should not happen. Since the code is executed in Start, I’m wondering if the delay is actually caused by a lag because when the Start method gets called, Unity might still be loading things in the background. That’s why I ased if you used a Debug.Log with Time.frameCount because this way, we would know if frame 1 was 10 seconds long or if the code block of the Start method got executed in multiple frames. That’s impossible to tell just by looking at the code.

hi, i’ll be honest i don’t know where to put the debug to see what you are trying to test hahah but i serialized the field for the delay and if i put 1 second it waits for 1 second , if i put 30 second it waits 30 seconds before scrolling , i don’t think we need to test it further

Sorry but i don’t get why it shouldn’t work in start :thinking:

This is the script

this is in unity

I agree with you. It is very unlikely that the game window lags for 30 seconds after you set the delay to 30 seconds, and lags 1 second if you set the delay to 1 second.

Sorry but i don’t get why it shouldn’t work in start :thinking:

Because, normally, “C#” does not wait. The rule is: Method code blocks gets executed line by line. The only exception is an IEnumerator method, which is a special method. According to the API, it is possible to define the Start method as a coroutine, which would allow us to implement a delay. You didn’t do that, yet the Start method seems to be executed with a delay. Maybe it already is a coroutine.

I would add this to Start:

Debug.Log(Time.frameCount + " --- Before StartCoroutine.");
Debug.Log(Time.frameCount + " --- After StartCoroutine.");

If the frame count value is the same, the Start method did not wait unless the game got somehow paused, which made the frame 30 seconds long.

If the frame count is not the same, you were right, and the Start method did wait.

So i did that and the frame count was the same for both the script which i use for delay the background scroll and terrain scroll, but why does it work so? and is it dangerous to leave it or use a coroutine like this? how should i solve this, please i did a short video to show you everything that happens, it all goes well and how i expected but this frame thing i don’t know if it would cause troubles in future projects, how should i do to have the same behavior?

at 0:37 i show that putting 1 second in the serialized field let the scroll of the terrain behave like i want, and later i put it at 10 seconds and it goes well too, it waits but the game don’t seem to be paused to me also
i was so happy i managed to get all going along and smooth :sob: so leaving it or using courutines like this in the start method is not good? how could i get the same behavior but in the right way

I’m checking on the internet and on several guides for coroutines and i’m seeing a lot of guys still using startcoroutine in the start method, maybe i did not explained well what i did, but it’s something like the guy underneath

oh i think i understood the mumbo jumbo i did, i’m an idiot

i did this part of course some several days ago so i forgot some pieces of codes i wrote, but i looked better and i saw that i put this

so the coroutine does not do a sterile wait, but it only waits for 3 second before he put that boolean value to true and then the update does its magic, if i remove this piece of codes, the wait does nothing;
so my final answer is this, from what i understood it is good to put coroutines in the start method but if i want the start method to do some delays from itself it would be better to define the Start method as a coroutine, in the other cases let’s say thatn general it would be better to not use coroutines with only yield return waitforseconds in them, but with already other pieces of codes i want in it to be affected by the delay

and last thing, so it is normal after all of this that the frames from the debug.log are the same(?)

Thanks a lot for sharing what you figured out. :slight_smile:

and last thing, so it is normal after all of this that the frames from the debug.log are the same(?)

Yes, it is. As aforementioned, normal methods get executed line by line without any delay. If the Start method gets executed in frame 1, the Debug.Log methods are expected to log “1” into the console.

For simplicity let’s assume that each like takes 0.01 second to get executed. The second Debug.Log might get executed after 0.02 seconds. However, that’s not automatically the next frame just because time has passed. A frame is not the time and does not depend on time. It is a predefined “package” of things that get executed. A frame could last 0.05 seconds, 3 seconds or whatever but the time does not determine what a frame is.

In frame 1, the entire Start method (and a lot more other things) got executed.

game_started gets set to true after the delay because you started a coroutine in another method (here: in Start). The variable was not set by the Start method but by the Wait method after the yield instruction. And the value of the variable got overridden x seconds after the level had been loaded because the Start method is one of the first methods that get called by Unity after a level was loaded.

I’m glad that we discussed this and that you shared your thoughts because I started wondering if I misunderstood C# and if there is some secret mechanism I haven’t known about yet. There is always something new to discover. :slight_smile:

See also:

Thank you for everything!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms