How to preload a scene with progress bar so it can start instantly?

So we have a huge level that takes like 10 seconds to start up from the moment we switch to it's scene - so I need to have the level preloaded with a progress bar (or at least some kind of animation) to cover it.

I found Application.LoadLevelAsync which turns out to be useless. It does let me load the level asynchronously for ten or so frames, but the problem is that it still takes the same amount of time after the LoadLevelAsync is done. It appears that the problem is that all the assets used by the level aren't actually loaded until we actually switch to the scene.

So how can I load the assets used by a scene asynchronously while still getting to draw the current scene? If I can't do that directly in one operation, how can I find what the assets used by a scene are, and how can I then preload those assets?

thanks!

P.S. since people asked for code, below is some loading code I use that isn't solving the problem - basically the async operation finishes very quickly, but then the loader screen stops drawing for many seconds until the loaded level draws it's first frame


public class MainMenu: MonoBehaviour     
{    
    public int counter = 0;     
    public AsyncOperation loadOp;

    void Start()    
    {   
        loadOp = Application.LoadLevelAsync("freewayLevel");    
    }

    void OnGUI()    
    {    
        string loadString = "Loading "+loadOp.progress.ToString()+"%";    
        //TEMP: trying to see if loadlevelaync works or not...    
        counter++;    
        loadString += " (" + counter.ToString() + ")";    
        GUILayout.Label(loadString);    
    }    
}

The real problem here is after loading complete, Unity3D need some time to init all scenes assets (activate all game objects / scripts takes time) so try to disable all GameObject on your next scene (in the editor) then when loading complete, you will need to manually (by code) activate one by one GameObjects and update the progress.

Hope it useful :slight_smile:

What if you use Appliciation.LoadLevelAdditive http://unity3d.com/support/documentation/ScriptReference/Application.LoadLevelAdditive.html

Have the 'loading' part in an intermediate scene, so it loads fast, then use LoadLevelAdditive to load the 'next scene' into the one with the loading bar.

You can have an empty scene as the default scene so the initial waiting time (showing the default Unity logo) comes to minimum, after that using loadLevelAsyn to load the big scene. As I said before, for your big scenes, you must manually disable all GameObjects then using a looping code to active them one by one while showing a progress bar. Try it once man, you can measure the actual progress without any lag at all !

Tell me if that’s still sound strange or difficult to you I will send you a sample project doing that. It’s really working my side, greatly works on both editor or an iPhone

I had the same problem with progress being only 0 or 1. This was solved by 3.5.0 release on 02/14/12.

So i have worked on a pre-loader system to avoid waiting and blank screens in between my levels. My issue : on mac, pc or mobile, the loader is working fine but again on the psp or ouya, every time, i have different behaviors or problems (like it will start from 0% reaching 11% then back to 0% then crash)

If someone want to check the asset and double check the code you are welcome as if it is working it can benefit the community maybe. You will need Unity Pro as i’m using a pro feature only : Async Dynamic Loading

https://www.dropbox.com/s/7hl1ribefn30rw7/LoadingAsync.unitypackage?dl=0

Thanks

Emmanuel

You can do this with yields see these scripts :

Object 1’s Script :

//1st Object Script

//Everything Is Loaded var.
public var bEverything_Is_Loaded : boolean = false;

//Object/Script access vars.
private var oMaster_Load_Script : Master_Load_Script;

function Awake () {

    //Connect to Objects and Scripts.
    oMaster_Load_Script = GameObject.Find("Game_Loader").GetComponent(Master_Load_Script);
}

function Start () {

    //Everything Is Loaded var.
    bEverything_Is_Loaded = true;

    //Wait For Master_Load_Script to Trigger Game Start Proper.
	while (oMaster_Load_Script.bEverything_Is_Loaded == false) {
	   yield;
    }
}

Object 2’s Script :

//2nd Object Script

//Everything Is Loaded var.
public var bEverything_Is_Loaded : boolean = false;

//Object/Script access vars.
private var oMaster_Load_Script : Master_Load_Script;

function Awake () {

    //Connect to Objects and Scripts.
    oMaster_Load_Script = GameObject.Find("Game_Loader").GetComponent(Master_Load_Script);
}

function Start () {

    //Everything Is Loaded var.
    bEverything_Is_Loaded = true;

    //Wait For Master_Load_Script to Trigger Game Start Proper.
	while (oMaster_Load_Script.bEverything_Is_Loaded == false) {
	   yield;
    }
}

Master Load Script :

//Master Load Script

//Everything Is Loaded var.
public var bEverything_Is_Loaded : boolean = false;

//Object/Script access vars.
private var o1st_Object_Script : 1st_Object_Script;
private var o2nd_Object_Script : 2nd_Object_Script;

function Awake () {

    //Connect to Objects and Scripts.
    o1st_Object_Script = GameObject.Find("1st_Object_Name").GetComponent(1st_Object_Script);
    o2nd_Object_Script = GameObject.Find("2nd_Object_Name").GetComponent(2nd_Object_Script);
}

function Start () {

    //Wait For 1st Object Script to Load.
	while (o1st_Object_Script.bEverything_Is_Loaded == false) {
	   yield;
    }
    
    //Wait For 2nd Object Script to Load.
    while (o2nd_Object_Script.bEverything_Is_Loaded == false) {
	   yield;
    }

    //Everything Is Loaded var.
    bEverything_Is_Loaded = true;
}

and everything will start in unison.

You can disable the main camera while doing this and display a second GUI camera with a progress bar, using counters connected to the yields for its progress.
You can have mid level load scripts that will check for their type of objects and then report to the Master Load Script, this way you can keep a more organised and manageable structure to your load checks.

Hope this helps.

This asset will allow you to incrementally load your scene without any need for pro features.
It works buy first loading up the new level without loading the game objects, then incrementally loading the objects in chunks. This should solve your problem.

If you have Unity pro you can use Application.LoadLevelAsync like you've mentioned. It does exactly what you want. When you call this function it returns immediately and you can check isDone or progress if the loading is done. You can even yield in a coroutine and wait for it to complete. During this time you can do what ever you like.

If you don't have pro the answer is simple: You can't do anything about it, you have to wait till it's loaded (or buy pro ;)).