- Home /
LoadLevelAsync never executes on a background thread?
In spite of the what the Unity docs say, it seems to me LoadLevelAsync
doesn't really work as advertised (or I'm screwing up of course -- which I'm trying to find out here).
I have a game made up of 2 scenes. A start scene where the player chooses a game type, and the main game scene where the game takes place. I'm trying to make it so that when the user chooses the game type, a transitional animation happens, after which the async loading of the level starts and in the meantime, I show the loading progress. Here's my code:
public void onGameTypeChosen(int gameType) {
StartCoroutine(startGame((GameType)gameType));
}
private IEnumerator startGame(GameType gameType) {
GameManager._GameType = gameType;
AsyncOperation loading = Application.LoadLevelAsync("Level1");
animator.Play("ZoomIn", -1, 0f);
progressIndicator.GetComponent<Animator>().Play("ProgressIndicatorFade", -1, 0f);
while (!loading.isDone) {
progressIndicator.endAngle = 360f * loading.progress;
yield return null;
}
}
my expected result would be that the animator
transitions to the 'zoom in' state, where the text that displayed the game type options fades into the camera, the another animator fades in the progress indicator and the thing keeps updating the loading progress in the UI until the level is fully loaded and the scene should just almost immediately show up.
What happens instead is that the zoom in animation happens, then the progress indicator fades in and it is already at 90%. After this, it takes about 5s on the editor and 30s on iOS to load the remaining 10% of the scene before it finally gets loaded. During this time (the infamous 10% left to load), the UI is clearly getting preempted and freezes at different intervals.
The first thing I did was print Thread.CurrentThread.IsBackground
before and after the LoadLevelAsync
call, as well as inside the while loop. It's always false
.
I also tried replacing the yield return null
with yield return loading
, since it wouldn't be the first time that Unity doesn't document things, like the special meaning of returning an AsyncOperation
from a coroutine. Still everything seems to be executing on the main thread anyway. The only difference is that if I yield return the op, the progress indicator doesn't even update.
Finally, I tried to explicitly dispatch LoadLevelAsync
on a background thread by doing:
Thread t = new Thread(() => Application.LoadLevelAsync("Level1"));
t.IsBackground = true;
t.Start();
But then I get the usual 'can only be called from the main thread."
So I have no idea what the deal is or how async loading is supposed to be used. At least for me, the code snippet in the docs does not work.