I created a loading screen to display a loading animation as the next scene is loading. I load the next scene asynchronously with:
yield return SceneManager.LoadSceneAsync(scene,LoadSceneMode.Additive);
And also set Application.backgroundLoadingPriority = ThreadPriority.Low;
, but the behaviour is still the same as a regular level load.
Am I missing something?
Expected behaviour:
- Exit level, and fade out.
- Loading screen appears.
- Once load is done, fade loading screen out.
- Fade in next scene.
What is happening:
- Exit level, and fade out.
- Loading screen appears, frozen
- Suddenly new scene fades in.
Once the load starts, the game just frezees, like with a regular Scene load.
I read that you have to set allowSceneActivation = false
, so you can fade the loading screen out, and then set it to true
to let unity finish loading, but this completelly freezes my game, like the async operation never finishes loading.
Answer
When you load an scene with SceneManager.LoadSceneAsync()
there are actually two things happening:
- The gameObjects of the scene are loaded into memory.
- Then the whole scene is enabled. All Awake() and Start() callbacks will be called for the objects in the scene.
The second step, enabling the scene, is what actually freezes unity, because unity is running all those initialization callbacks in your scripts in a single cycle.
Indeed setting SceneManager.LoadSceneAsync().allowSceneActivation
to false
will make the async operation to complete only the first step of the process, and will wait until it's set to true
to begin the second part of the process.
But if you set allowSceneActivation
to false
and yield on the callback like this, you will freeze your game for good:
AsyncOperation AO = SceneManager.LoadSceneAsync(scene,LoadSceneMode.Additive);
AO.allowSceneActivation = false;
yield return AO;
//Fade the loading screen out here
AO.allowSceneActivation = true;
Why? Because you are telling the Async operation to not proceed with the second step of the scene load, so the operation will never be completed.
If you want to know when the first part of the operation is ready, to then proceed with the second one, you have to rely on AsyncOperation.progress
. This value will stop at 0.9f
once it's waiting for the allowSceneActivation
flag.
It should be something like this:
AsyncOperation AO = SceneManager.LoadSceneAsync(scene,LoadSceneMode.Additive);
AO.allowSceneActivation = false;
while(AO.progress < 0.9f)
{
yield return null
}
//Fade the loading screen out here
AO.allowSceneActivation = true;
If you want the scene activation to not freeze your game, then you should keep your Awake and Start callbacks to a minimun, and initialize your scripts in a coroutine through several cycles.
No comments:
Post a Comment