Hello!
I have found old code of me and I have to admit I don’t understand it fully
Here is the code:
private IEnumerator Start() {
yield return StartCoroutine( LoadSceneAndSetActive(startScene));
yield return StartCoroutine( FadeOutFullscreenBrightImage(1.0f) );
}
private IEnumerator LoadSceneAndSetActive(string sceneName) {
yield return SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
Scene newlyLoadedScene = SceneManager.GetSceneByName(sceneName);
SceneManager.SetActiveScene(newlyLoadedScene);
}
private IEnumerator FadeOutFullscreenBrightImage(float fadeOutTime) {
while(condition) {
...
yield return null;
}
yield return null;
}
Here is the stuff I don’t understand fully:
Is there a difference between yield return StartCoroutine(Foo()) and just StartCoroutine(Foo())?
When I call yield return StartCoroutine( LoadSceneAndSetActive(startScene)); it seems like execution is passed to LoadSceneAndSetActive() (Start is paused) so I assumed when I call yield return SceneManager.LoadSceneAsync() I assumed LoadSceneAndSetActive() is paused until LoadSceneAsync() is done. But it seems like LoadSceneAsync() immediately returns. Is this true?
With this code I want to load a scene and fade out a white fullscreen quad. But it seems like the scene loading and fading is done in parallel. Isnt my code bad then? Shouldnt I WAIT for the scene loading to be finished?
Do you know anything about enumerators in C#?
_geo1
August 28, 2021, 4:07pm
3
The manual has the answers you seek. If you yield it then it will be sequential. Unity - Scripting API: MonoBehaviour.StartCoroutine
2 &3) LoadSceneAsync() returns an AsyncOperation object. You need wait for it to finish.
There is an example in the manual: Unity - Scripting API: SceneManagement.SceneManager.LoadSceneAsync
Coroutines in a nutshell:
Hey Epoch, here’s how it goes down. A coroutine is just an IEnumerator object, and you make one by just calling a coroutine.
When you do that, nothing happens. It’s like a water pump that needs to have its crank pumped, but nobody is pumping it so it sits there and does nothing.
In Unity there’s a special agreement: if you hand that IEnumerator object into StartCoroutine(), which is a method belonging to the object where that StartCoroutine() call is located, what Unity does is starts “pumpin…
Coroutines are an IEnumerator object. They have their own internal state. It’s different from just calling InvokeRepeating(), which would restart a fresh function call each time.
Here is ALL you need to know about coroutines in Unity:
they are an IEnumerator, also known in some languages as a Generator. It is an object with a .MoveNext() method on it that “yields” the next thing with each subsequent call. That is what you create by calling an IEnumerator: you create the object, you do NOTHIN…
Splitting up larger tasks in coroutines:
Technically, yeah, there’s always a way. But in practice, in the general sense it can get really hairy.
Also, in the particular case of adding lots of GameObjects, I know they’re not linear: last I checked, adding 1000 GameObjects is WAY more than 10x slower than adding 100 Gameobjects, I presume due to inefficiencies in newly-added stuff, not sure/ No way to tell with a closed-source engine like Unity.
Trying to tie into system timers and judge how long things have taken so far will get you …
Coroutines are NOT always an appropriate solution: know when to use them!
There’s never a need. As @PraetorBlue pointed out in a recent post of his, nobody NEEDS coroutines.
They do solve a certain class of problem nicely however, primarily problems of sequencing a set of data or events to happen.
Coroutines CAN be interrupted and restarted but doing so exponentially increases your chance of a bug, negating a lot of their inherent benefits.
A lot of human behaviors are good coroutines: “Go take a shower.”
So that breaks down to:
get undressed
start the shower
…