Search Unity

LoadSceneAsync allowSceneActivation Help?

Discussion in 'Scripting' started by ethanproia, Aug 20, 2019.

  1. ethanproia

    ethanproia

    Joined:
    Feb 27, 2019
    Posts:
    7
    Hello all,

    Very new to scripting and C# in Unity but been working to learn and understand.
    Writing a script for an app splash screen that is intended to do the following:

    1) Display splash screen animation for 8 seconds
    2) Simultaneously & asynchronously load the next scene as soon as the splash animation begins running.
    3) allowSceneActivation = true and transition to the next scene once the 8-second timer has expired so that the scene will be fully loaded by the time the animation has finished.

    I feel like I'm very close but I don't understand why I can't call "ao" under my void Update(). I understand that allowSceneActivation dictates whether LoadSceneAsync is acted upon or held after being loaded into memory.

    My current script is as follows:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5.  
    6. public class SceneFade_Time_v2 : MonoBehaviour
    7. {
    8.     [SerializeField]
    9.     private float loadDelay = 8f;
    10.     [SerializeField]
    11.     private string sceneToLoad;
    12.  
    13.     private float timeElapsed;
    14.  
    15.     void Start()
    16.     {
    17.        StartCoroutine(AsyncLoad());
    18.     }
    19.     private void Update()
    20.         {
    21.             timeElapsed += Time.deltaTime;
    22.    
    23.             if (timeElapsed > loadDelay)
    24.             {
    25.                 ao.allowSceneActivation = true;
    26.             }
    27.         }
    28.    
    29.     IEnumerator AsyncLoad()
    30.     {
    31.         AsyncOperation ao = SceneManager.LoadSceneAsync(sceneToLoad, LoadSceneMode.Additive);
    32.         ao.allowSceneActivation = false;
    33.         while (ao.progress < 0.9f)
    34.         {
    35.             yield return null;
    36.         }
    37.     }
    38. }
    This script just loads the splash scene and never switches to the next scene determined by sceneToLoad. I feel like I'm missing something very simple and fundamental.

    Any and all help or suggestions are much appreciated.

    Thanks very much!
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    When you declare a variable inside a function, that variable can only be used inside that function. (This is called a "local" variable.)

    If you want the variable to be usable everywhere inside the class, declare it at the class level, like you are doing with timeElapsed.

    Once you've done that, you should also add an "if (ao != null)" check in your Update function, to make sure you don't try to dereference it if hasn't been initialized yet. (In this case, this won't matter if the rest of the code works correctly, but it's a good practice.)


    Also, the way your code is currently structured, you don't need a coroutine. The loop where your coroutine waits for ao to be 90% finished doesn't matter, because it doesn't do anything after the wait. You could just put the first two lines of your AsyncLoad() function into a regular, non-coroutine function and avoid all the "yield" stuff if you wanted.

    Alternately, you can get rid of Update by putting the wait that actually matters inside of the coroutine, like this:
    Code (CSharp):
    1.     IEnumerator AsyncLoad()
    2.     {
    3.         // Tell the scene to start loading
    4.         AsyncOperation ao = SceneManager.LoadSceneAsync(sceneToLoad, LoadSceneMode.Additive);
    5.         ao.allowSceneActivation = false;
    6.  
    7.         // Wait for the specified delay
    8.         yield return new WaitForSeconds(loadDelay);
    9.  
    10.         // Give the scene permission to activate when it's ready
    11.         ao.allowSceneActivation = true;
    12.     }
    In this version, you can leave ao as a local variable, since it will only be referenced from inside of this function.
     
  3. ethanproia

    ethanproia

    Joined:
    Feb 27, 2019
    Posts:
    7
    Wow thank you so much - that makes a ton of sense. Really appreciate you taking the time to explain everything!
     
  4. ethanproia

    ethanproia

    Joined:
    Feb 27, 2019
    Posts:
    7
    Tried your last solution which seems the most elegant, however, the new Scene is not activating and it's just hanging at the end of the first scene. Any idea why this would be? Thought it may have been an Editor error and tried deploying to a device but still no luck.
     
  5. ethanproia

    ethanproia

    Joined:
    Feb 27, 2019
    Posts:
    7
    Solved it - didn't realize coroutines didn't run like regular functions and had to be initialized. Working perfectly, thank you again for your help!