4

I'm creating a Unity application targeting the Samsung Gear VR. I currently have two scenes:

  1. The initial scene
  2. Second scene, with big quantity of data (it takes too much time to load the scene).

From the first scene, I want to load the second scene in background, and switch to it once it has been loaded. While the new scene is loading in background, the user should keep the ability to move their head to see any part of the VR environment.

I'm using SceneManager.LoadSceneAsync but it's not working:

// ...

StartCoroutiune(loadScene());

// ...

IEnumerator loadScene(){
        AsyncOperation async = SceneManager.LoadAsyncScene("Scene", LoadSceneMode.Single);
        async.allowSceneActivation = false;
        while(async.progress < 0.9f){
              progressText.text = async.progress+"";
        }
       while(!async.isDone){
              yield return null;
        }
        async.allowSceneActivation = true;
}

With that code, the scene never changes.

I've tried this the typical SceneManager.LoadScene("name") in which case the scene changes correctly after 30 seconds.

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
adlagar
  • 877
  • 10
  • 31

1 Answers1

8

This should work

    while(async.progress < 0.9f){
          progressText.text = async.progress.ToString();
          yield return null;
    }

Secondly, I've seen cases where isDone is never set to true, unless the scene has activated. Remove these lines:

    while(!async.isDone){
          yield return null;
    }

On top of that, you are locking your code in that first while loop. Add a yield so the application can continue loading your code.

So your entire code looks like this:

IEnumerator loadScene(){
    AsyncOperation async = SceneManager.LoadAsyncScene("Scene", LoadSceneMode.Single);
    async.allowSceneActivation = false;
    while(async.progress <= 0.89f){
          progressText.text = async.progress.ToString();
          yield return null;
    }
    async.allowSceneActivation = true;
}

The biggest culprit to your problem is the locking in the first while loop, though.

Riaan Walters
  • 2,587
  • 2
  • 18
  • 30
  • 3
    You covered every possible problem but in this case, the problem of the scene not loading is simply because of `async.isDone`. The `async.isDone` should be removed. You are right about the `yield return null` statement but this has nothing to do with float-point comparison. – Programmer Oct 13 '16 at 07:51
  • Unity stops loading a scene at 0.9, correct? I'm a bit rusty on this, but isnt it possible due to floating point precision for it to actually be 0.899999999 which would in effect never satisfy the where clause? – Riaan Walters Oct 13 '16 at 07:53
  • @ParadoxForge Yes but normally floating point has some degree of error correction. I would debug by reducing the number t something very low (e.g. 0.1) to make sure it gets triggered at all. – Qix - MONICA WAS MISTREATED Oct 13 '16 at 08:04
  • 2
    @ParadoxForge I understand what you are trying to say but this does not apply here. The `async.progress` will always return the exact value of `0.9` when finished loading. It will **not** return any other value when done loading. It is even ok and safe to do `if(async.progress == 0.9f){async.allowSceneActivation = true;}` You can read more about this [here](http://www.alanzucconi.com/2016/03/30/loading-bar-in-unity/). As for your `0.89`, this will likely cause problem as you will be activating a scene that has not yet 100% loaded. The rest of your answer is good. – Programmer Oct 13 '16 at 08:21
  • 1
    Thank you @Programmer for the elaboration, i will edit the answer – Riaan Walters Oct 13 '16 at 08:22
  • 2
    You are welcome. One more thing. This [only](https://docs.unity3d.com/550/Documentation/ScriptReference/AsyncOperation-allowSceneActivation.html) applies when `allowSceneActivation` is set to `false`. In this case, it is set to `false` in the beginning by OP. – Programmer Oct 13 '16 at 08:25
  • @adri1992 was this the answer to your question? – Riaan Walters Oct 13 '16 at 11:11
  • I've tried it and works fine =) Thanks so much! But now I've another question... The progress gets to 0.9 too fast (1 or 2 seconds), but then, the scene is "frozen", the VR environment is black (I can see correctly only the part that was rendered before the AsyncOperation has finished), and the scene changes after 25 seconds approximately =( Any idea? – adlagar Oct 13 '16 at 13:23
  • I'd start a new question as what you are asking now is not related to the original problem, remember to close this one by mark this as the answer if you consider this to help your original problem. That way we keep the Stackoverflow questions cleaner. – Riaan Walters Oct 13 '16 at 13:32
  • I will do it =) Thanks for all! – adlagar Oct 13 '16 at 13:45
  • @Programmer everything alright? I have missed your contributions to understanding the nuances and nightmares of Unity. – Confused Feb 05 '19 at 03:19