/// <summary> /// Coroutine which stacks the given scene name on top of existing scene. /// Tracks existing scene name in stack such that it can be set active later on when given scene is popped. /// Example: In BoardScene (BS), Pause Button is clicked which will trigger PauseScene (PS) to be stacked on top /// - In stack, BS will be pushed. => Stack (BS) /// - PS will be marked as the active scene => Active Scene (PS) /// In Pause Menu, if now Level select is clicked, LevelSelectScene (LS) needs to be stacked on top /// - In stack, PS will be pushed. => Stack (PS, BS) (PS is top) /// - LS will be marked as the active scene => Active Scene (LS) /// </summary> /// <param name="uiOperation"></param> /// <returns></returns> private IEnumerator LoadAdditiveSceneAsync(UIOperation uiOperation) { BeginSafetyOperation(); m_sceneCallStack.Push(SceneManager.GetActiveScene().path); var popupSceneName = uiOperation.SceneName; AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(popupSceneName, LoadSceneMode.Additive); while (!asyncLoad.isDone) { yield return(null); } // explicitly need to set this active scene since it doesnt happen automatically in additive load var popupScene = SceneManager.GetSceneByName(popupSceneName); while (!popupScene.isLoaded) { yield return(null); } yield return(StartCoroutine(SetActiveScene(popupScene))); uiOperation.Complete(); GameManager.Instance.EventAggregator.Publish(SceneChangeEvent.Build(popupSceneName)); EndSafetyOperation(); }
/// <summary> /// Coroutine which pops the top of the stack and /// expects top of the stack to be same as uiOperation.SceneName /// It also pops from the stack and after popping, if there are two scenes in memory, /// it disambiguates by marking the correct base scene as the active scene. /// </summary> /// <param name="uiOperation"></param> /// <returns></returns> private IEnumerator UnloadAdditiveSceneAsync(UIOperation uiOperation) { BeginSafetyOperation(); var popupSceneName = uiOperation.SceneName; AsyncOperation asyncLoad = SceneManager.UnloadSceneAsync(popupSceneName); while (!asyncLoad.isDone) { yield return(null); } #if UNITY_EDITOR //Debug.Log("Active scene before: " + SceneManager.GetActiveScene().name); #endif string baseScenePath = m_sceneCallStack.Pop(); // only need to set scene active, if there were >= 2 scenes // if after pop, stack is empty => now there is only 1 active scene // we dont need to set the only scene as active scene if (m_sceneCallStack.Count != 0) { var baseScene = SceneManager.GetSceneByPath(baseScenePath); yield return(StartCoroutine(SetActiveScene(baseScene))); } uiOperation.Complete(); GameManager.Instance.EventAggregator.Publish(SceneChangeEvent.Build(SceneManager.GetSceneByPath(baseScenePath).name)); EndSafetyOperation(); }
/// <summary> /// Coroutine which removes all the other scenes and loads the given scene name /// </summary> /// <param name="operation"></param> /// <returns></returns> private IEnumerator LoadSingleSceneAsync(UIOperation operation) { BeginSafetyOperation(); AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(operation.SceneName, LoadSceneMode.Single); while (!asyncLoad.isDone) { yield return(null); } m_sceneCallStack.Clear(); operation.Complete(); GameManager.Instance.EventAggregator.Publish(SceneChangeEvent.Build(operation.SceneName)); EndSafetyOperation(); }