- Home /
how to use LoadLevelAsync to make a progress bar
I want to make my own progress bar when switching between levels in Unity.
I've tried the following code:
IEnumerator LoadLevel1() { AsyncOperation async = Application.LoadLevelAsync("level1");
while (!async.isDone)
{
print(async.progress);
yield return 0;
}
}
It doesn't work, and Unity gives the following error message at runtime:
"m_ThreadCheck && !Thread::EqualsCurrentThreadID(m_ThreadID)"
How is LoadLevelAsync meant to be used?
to complement this solution: http://answers.unity3d.com/questions/7846/how-do-i-make-a-progress-bar.html
Answer by Eric5h5 · Mar 21, 2010 at 12:13 AM
I'm not sure this is actually possible at the moment...
function Start () {
DontDestroyOnLoad(this);
print ("Loading...");
yield LoadLevelWithProgress ("Level1");
print ("Loading complete");
}
function LoadLevelWithProgress (levelToLoad : String) {
var async = Application.LoadLevelAsync(levelToLoad);
while (!async.isDone) {
print ("%: " + async.progress);
yield;
}
}
That works, except async.progress only ever returns 0. You can still have some kind of animated loading indicator, but I don't see how a progress bar is possible, since you never know what the progress actually is. I would guess that's a bug.
Just adding here, as Whitebread009 pointed out in another answer, it is possible at least since december (9 months after Eric's post). And I confirm it keeps working up to date, on Unity 3.5
@Eric5h5 , please can you tell me what is the role of the yield in the while loop. Thanks
@moghes Unity3D scripts aren't multi thread. The yield
inside the while let the processor go out of it and run everything else for 1 iteration, then back inside the loop. Otherwise, it would be stuck inside the loop until it's finished. It's not an easy question, dude. Try reading more here: http://www.altdevblogaday.com/2011/07/07/unity3d-coroutines-in-detail/ -> this might be the most linked article about coroutines outside *.unity3d.com ! :P
Someone knows how the progress returns always 0 in the loop please ?
Answer by Whitebread009 · Dec 21, 2011 at 06:42 PM
After playing with this for a while I discovered that AsyncOperation.progress is in fact functional, however when run in the editor you will never receive the appropriate value from it. In the builds that I have done I have used the progress variable with success to create a progress bar for loading in between levels.
I hope this helps someone.
It did help me and I can confirm it works fine except in the editor!
Answer by logicalerror · Sep 17, 2014 at 01:33 PM
This is an old post, but I couldn't find the solution to my LoadLevelAsync problems online and this is one of the first posts that shows up in Google. So I'm just posting my discovery here hoping it'll help others in the future:
I discovered that LoadLevelAsync behaves like LoadLevel depending on which thread it's running.
Unity has this nasty undocumented behavior that in Start/Awake it's running on the main thread (which makes LoadLevelAsync behave like LoadLevel somehow, perhaps it accidentally gets synchronized with other things running on that thread) and everywhere else it might not run on the main thread. Update seems to make LoadLevelAsync asynchronous for me .. on PC at least, haven't tested it on other platforms yet.
Thank you so much for this answer! I was using the LoadLevelAsync() method from the update() and I had a few seconds delay loading the next scene. Now I call the method from another script and it works perfectly. You saved me a lot of time!
I don't think that is related to a thread issue since every scripting callback runs on the main thread. However the problem is most likely when you call it while another level is still loading. So when you do something in Start or Awake on a GameObject that is loaded along with a scene, the scene loading is not finished yet but you try to switch to a new scene immediately.
A simple yield return null;
before your actual LoadLevelAsync call would probably "fix" this as after the yield one frame has passed and the initial scene loading has finished.
Note: maybe a second yield is required as well since the very first frame after a scene load is a "special" frame.
Answer by Jack Al · Jul 04, 2014 at 12:26 PM
here's what you need:
private IEnumerator loadAsync(string levelName)
{
AsyncOperation operation = Application.LoadLevelAdditiveAsync(levelName);
while(!operation.isDone) {
yield return operation.isDone;
Debug.Log("loading progress: " + operation.progress);
}
Debug.Log("load done");
}
How can make this script work in a buttom, here my script. using UnityEngine; using System.Collections; public class LOADSCENE6 : $$anonymous$$onoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void LoadLevel () { Application.LoadLevel("New_SOFA_Outra"); } }
Answer by Evil-Dog · Jul 15, 2011 at 03:23 PM
async.progress is not functional at this moment. If you look around in other similar questions there's a confirmation that it's not implemented even in Unity 3.x
Surely something we should bump up in the feature requests
Oh shit……$$anonymous$$y boss tell me to get the Right percentage% of progress when LoadLevelAsync doing~~! God!!
Yeah I work with a preloader as well, how long are your loading times? I simply have an animated Loading... while it loads for the few seconds it needs, if the load time is defininitly longer, here's an idea for you, basically fake the progress bar, test the loading time on the device and make a fake % progress using that time with a dampener toward the end so that if it takes longer it will go up to 90% at normal speed and start slowing down and never reach 100%. In my humble opinion, if you really need a % that'd work decently.
Also, you may want to consider this technique, I did my preloading by having scenes that each contain a special object with a special script that holds all my assets that I'll need, mostly prefabs so I can call LoadLevelAsyncAdditive and know when they're done loading. These scripts are what I call Spawn databases, so I have like CarSpawnDB that is set to DontDestroyOnLoad and that is loaded additively during the preloader animation and once in the new level, my gameplay level, I can spawn the cars with Instantiate and refering to my CarSpawnDB "singelton"
I bet this is broken because someone forgot to add in a f
somewhere... :D
Your answer
Follow this Question
Related Questions
Loading Progress using UNET 2 Answers
app freeze and threading 2 Answers
Switch Levels with Async and still display progress 2 Answers
How to load scene when async.progress is 0.9? 0 Answers
Upgraded to 2017.1.0f3 and Now Scenes Are Not Loading Properly? 1 Answer