Asynchronous loading freeze

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.