I am trying to load a scean asynchronously and after the loading has finished, I want the loader to display a button that when pressed, the loaded scene will be activated. However, I get a freeze whenever I try to do this. Here is my code:
var emptyBar : Texture2D;
var fullBar : Texture2D;
private var progress : float = 0;
private var asyncLoader : AsyncOperation;
private var loadingFinished : boolean = false;
function Start(){
StartCoroutine(Load());
Application.backgroundLoadingPriority = ThreadPriority.Low;
Screen.showCursor = false;
}
function Update () {
progress = asyncLoader.progress;
}
function Load(){
loadingFinished = false;
asyncLoader = Application.LoadLevelAsync(Game.loadScene);
asyncLoader.allowSceneActivation = false;
if(asyncLoader.isDone) loadingFinished = true;
yield asyncLoader;
}
function OnGUI(){
GUI.BeginGroup(Rect(Screen.width/2-350, Screen.height/2 + 150, 700, 22));
GUI.DrawTexture(Rect(0, 0, 700, 22), emptyBar, ScaleMode.ScaleToFit);
GUI.DrawTexture(Rect(0, 0, Mathf.Round(700*progress), 22), fullBar, ScaleMode.StretchToFill);
GUI.EndGroup();
if(loadingFinished){
Screen.showCursor = true;
print("SCENE LOADED");
if(GUI.Button(Rect(10, 10, 100, 30), "ACTIVATE")){
asyncLoader.allowSceneActivation = true;
}
}
GUI.Label(Rect(0, Screen.height/2-30, Screen.width, 60), "Loading Screen");
}
The progress bar gets filled almost to 100% but then it stops and the no button is shown. The LoadLevelAsync does not finish loading the level because if I stop the game in the editor, the editor freezes and I need to exit it via the task manager.
I can make the level load normaly with LoadLevelAsync and activate it as soon as it has finished loading, but I need to display that button which will activate the scene. So instead of checking the isDone value of the async operation and activating the scene, I asign a TRUE value to the boolean variable “loadingFinished”. I am pretty sure that this is what breaks the loader. However I can’t seem to find a solution to this. Can anybody share some experience and point me in the right direction ?
Cheers!
The problem is in your load function. your if statement:
if(asyncLoader.isDone) loadingFinished = true;
is doing nothing for you. It gets skipped over then the level gets loaded.
This should work
function Load(){
loadingFinished = false;
asyncLoader = Application.LoadLevelAsync(Game.loadScene);
asyncLoader.allowSceneActivation = false;
yield asyncLoader;//the yield will return when the load is complete
loadingFinished = true;
}
Hi and thanks for your fast answer. My first try was to make the Load function exactly as you suggested but this method still results in the same freeze. I feel that setting “allowSceneActivation” to false is the thing that breaks the code.
The load function works if it’s like this:
function Load(){
asyncLoader = Application.LoadLevelAsync(Game.loadScene);
yield asyncLoader;
if(!asyncLoader.isDone) asyncLoader.allowSceneActivation = false;
else asyncLoader.allowSceneActivation = true;
}
After some debugging I found out that asyncLoader.progress never actually reaches 100%. So for some reason LoadLevelAsync does not load the level completely I guess. But that only happens when I set asyncLoader.allowSceneActivation = false; after I call LoadLevelAsync. So for some reason, setting allowSceneActivation to false prevents LoadLevelAsync from completion. There’s gotta be a way to work around that! I’m sure! I’ll keep you updated if I find something out.
So I finaly got it to work! I don’t know why, but it seems that the progres never reaches 1.0 no matter what. So the closest to 1 that it gets is 0.9 (every time). Having said that, I wrote the Load function like that:
asyncLoader = Application.LoadLevelAsync(Game.loadScene);
while(!asyncLoader.isDone){
if(asyncLoader.progress >= 0.9f){
asyncLoader.allowSceneActivation = false;
loadingFinished = true;
break;
}
yield;
}
yield asyncLoader;
When loadingFinished is true, a button appears and if clicked, asyncLoader.allowSceneActivation is set to true and the scene loads. It creates a little hiccup though…something I wouldn’t expect because the level should have already been loaded. Anyway,I’m interested to see if there’s a better solution as this feels a little unnatural to me.
After so many years I have exactly the same problem with unity 5.0.2f1. It stops at 90% and isDone is not set to true if allowSceneActivation is set to false.
I too, am having the exact same problem. So many attempts, so many different answers, none work. Always, without fail, jumps from 0% to 90%, hangs, loads scene. isDone is never, no matter how hard I try, set to true.
This has been a problem for so many time. 2016 and still no solution…
4 Likes
If you have asyncLoader.allowSceneActivation = false, it will never reach 100%. The progress loaded all the gameobjects to memory till 90% and rest 10% is for activating it. That is when all Start, Awake, OnEnable are called. So if sceneActivation is set to false, last 10% part will never be called.