Search Unity

Implementation of loading animation that moves asynchronously during scene transition

Discussion in 'Editor & General Support' started by nax_unity, Jun 27, 2020.

  1. nax_unity

    nax_unity

    Joined:
    Jan 24, 2018
    Posts:
    63
    Scene loading is done asynchronously using "SceneManager.LoadSceneAsync".

    However, when transitioning the scene from "SceneManager.LoadSceneAsync" start and load end
    The main thread hangs for a few seconds and the loading animation hangs.

    Scenes with a large number of objects to read will take longer to stop.

    The loading animation only rotates the Image constantly,
    I changed the processing method to "Start Coroutine", "Task", and "Animator",
    It wasn't resolved.

    Is there an asynchronous process that does not stop the animation even when the scene transitions?

    Development environment
    Unity 2018.4.22f1
     
    yuki2006 likes this.
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,914
    What does your code look like?
     
  3. nax_unity

    nax_unity

    Joined:
    Jan 24, 2018
    Posts:
    63
    This is my asynchronous loading code.

    public IEnumerator loadSceneAsync( string a_scene )
    {
    yield return null;

    //Begin to load the Scene you specify
    AsyncOperation asyncOperation = SceneManager.LoadSceneAsync( a_scene, LoadSceneMode.Additive );

    //Don't let the Scene activate until you allow it to
    asyncOperation.allowSceneActivation = false;

    //When the load is still in progress, output the Text and progress bar
    while (!asyncOperation.isDone)
    {
    // Check if the load has finished
    if (asyncOperation.progress >= 0.9f)
    {
    asyncOperation.allowSceneActivation = true;
    }

    yield return null;
    }
    unloadScene();
    }

    public void unloadScene()
    {
    Resources.UnloadUnusedAssets();
    if( _unloadSceneName.Equals( "" ) ){
    }else{
    SceneManager.UnloadScene( _unloadSceneName );
    _unloadSceneName = "";
    }
    }
     
  4. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I'd be interested if someone has a way around this, but to my knowledge, you're going to have hiccups in your loading screen any time the main thread does something expensive. I initially had a cool loading screen with lots of particle effects and animation. But in practice, it would basically look like a slide show as the main thread locked up for a second at a time while loading the next scene. I opted for a simple loading screen that didn't look as bad when it was run at 1-2 FPS.
     
  5. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,914
    So there is a concept in Unity called "Scene Activation", and while I haven't seen a great explanation of exactly what it is, it seems to be the final step of scene loading and all of it seems to need to happen on the main thread. So if your scene is nontrivial, despite all your best efforts, I think you will end up with some hiccuping during scene activation. I'm not 100% sure what exactly happens during scene activation, but one way to try to improve things would be to run the profiler and see what's taking time during scene activation, especially during frames which are longer than your target. Maybe it's some of your code, perhaps Start() or Awake() methods of your objects. In this case you might be able to find the worst offenders and break their work up into multiple frames.

    At some level though I'm not sure anything can be done.
     
    Last edited: Jun 27, 2020
  6. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I won't hijack this thread, but just reiterating that I did what you suggested maybe a year ago, profiling the scene load process to see what was so expensive about it, and what exactly was happening when the UI locked up upon activating the scene. Basically, nearly all the time was spent on Start/Awake calls on all the objects in the scene, just activating everything. I decided it wasn't at all worth changing my entire architecture (adding some kind of delayed activation mechanism) just to get my "Loading" screen to look a little prettier, so I moved on. But I wouldn't be surprised if that frame lock-up was just the frame when all the newly loaded objects are activated. So, you've probably provided good advice here, assuming someone is willing to put in the effort.
     
    PraetorBlue likes this.
  7. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,914
    That's awesome to hear! I felt a little uneasy giving this advice because I've never tried it personally and wasn't sure if that's all there was to it.
     
  8. nax_unity

    nax_unity

    Joined:
    Jan 24, 2018
    Posts:
    63
    Thank you for the information.

    Until the problem can be solved, I will change the correspondence of the loading screen to another display method.

    I used "Handheld.StartActivityIndicator()" for native apps,
    The indicator has stopped being displayed since iOS 13.
    The same code works on iOS 12.

    The question will change, but do you know the cause?

    #if UNITY_EDITOR || UNITY_IOS
    [SerializeField] private UnityEngine.iOS.ActivityIndicatorStyle _iosStyle;
    #endif

    private void Awake ()
    {
    #if UNITY_IOS
    Handheld.SetActivityIndicatorStyle( _iosStyle );
    #endif
    }

    public void Show()
    {
    StartCoroutine(StartActivityIndicator());
    }

    private IEnumerator StartActivityIndicator(){
    Handheld.StartActivityIndicator();
    yield return new WaitForSeconds(0);
    }

    public void Hide(){
    Handheld.StopActivityIndicator();
    }
     
  9. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Sorry, no idea. You should start a new thread with a relevant title since you have a new, unrelated question.
     
    PraetorBlue likes this.