/// <summary> /// Loads the entry scene (build index 1) if required and unloads all other scenes (except bootstrap [build index 0]) /// </summary> /// <param name="action">Called when the process is completed.</param> public void ReturnToEntry(UnityAction <SceneProcessState> action) { if (isEntryLoaded) { Debug.LogWarning("Attempt to load menu scene (" + Entry.name + ") while its already loaded.\nNo actions taken!"); return; } SceneProcessState nState = new SceneProcessState(); nState.setActiveScene = 1; nState.unloadTargets = new List <int>(); nState.loadTargets = new List <int>(); var loadedScenes = SceneManager.sceneCount; for (int i = 0; i < loadedScenes; i++) { var scene = SceneManager.GetSceneAt(i); if (scene.isLoaded && scene.buildIndex != 0) { nState.unloadTargets.Add(scene.buildIndex); } } nState.loadTargets.Add(1); StartCoroutine(ProcessState(nState, action)); }
/// <summary> /// Unloads multiple scenes if they are loaded and calls the indicated action when the process is complete /// </summary> /// <param name="scenes">The scenes to be unloaded</param> /// <param name="action">The action to call when complete</param> public void Unload(IEnumerable <int> scenes, UnityAction <SceneProcessState> action) { var nState = new SceneProcessState() { unloadTargets = new List <int>(), loadTargets = new List <int>(scenes), setActiveScene = -1, }; StartCoroutine(ProcessState(nState, action)); }
/// <summary> /// Loads one scene while unloading another raising started, updated and completed events as required. /// </summary> /// <param name="from">The scenes to transition from, this will be unloaded</param> /// <param name="to">The scenes to transition to, this will be loaded</param> ///<param name="activeScene">The scene to set as thee active scene</param> /// <param name="action">Called when the process completes</param> public void Transition(IEnumerable <int> from, IEnumerable <int> to, int activeScene, UnityAction <SceneProcessState> action) { SceneProcessState nState = new SceneProcessState() { loadTargets = new List <int>(to), unloadTargets = new List <int>(from), setActiveScene = activeScene }; StartCoroutine(ProcessState(nState, action)); }
private IEnumerator ProcessState(SceneProcessState state, UnityAction <SceneProcessState> action) { if (Started != null) { Started.Raise(this, state); } OnStarted.Invoke(state); yield return(new WaitForEndOfFrame()); List <AsyncOperation> loadOperations = new List <AsyncOperation>(); List <AsyncOperation> unloadOperations = new List <AsyncOperation>(); if (state.loadTargets != null) { foreach (var scene in state.loadTargets) { if (!Scenes.IsSceneLoaded(scene)) { var op = SceneManager.LoadSceneAsync(scene, LoadSceneMode.Additive); op.allowSceneActivation = true; loadOperations.Add(op); } } } if (state.unloadTargets != null) { foreach (var scene in state.unloadTargets) { var op = SceneManager.UnloadSceneAsync(scene); op.allowSceneActivation = true; unloadOperations.Add(op); } } int loadCount = loadOperations.Count; int unloadCount = unloadOperations.Count; while (loadOperations.Count > 0 || unloadOperations.Count > 0) { loadOperations.RemoveAll(p => p.isDone); unloadOperations.RemoveAll(p => p.isDone); float loadProgress = loadCount - loadOperations.Count; float unloadProgress = unloadCount - unloadOperations.Count; foreach (var op in loadOperations) { loadProgress += op.progress; } foreach (var op in unloadOperations) { unloadProgress += op.progress; } if (loadCount > 0) { loadProgress = loadProgress / loadCount; } else { loadProgress = 1f; } if (unloadCount > 0) { unloadProgress = unloadProgress / unloadCount; } else { unloadProgress = 1f; } state.loadProgress = loadProgress; state.unloadProgress = unloadProgress; if (loadCount > 0 && unloadCount > 0) { state.transitionProgress = (loadProgress + unloadProgress) / 2f; } else if (loadCount > 0) { state.transitionProgress = loadProgress; } else { state.transitionProgress = unloadProgress; } if (Updated != null) { Updated.Raise(this, state); } OnUpdated.Invoke(state); yield return(new WaitForEndOfFrame()); } SetSceneActive(state.setActiveScene); if (Completed != null) { Completed.Raise(this, state); } OnCompleted.Invoke(state); if (action != null) { action.Invoke(state); } }