private static void SceneManagerSceneUnloaded(Scene scene) { if (mixedRealityPlayspace == null) { // If we unloaded our playspace, see if another one exists SearchForAndEnableExistingPlayspace(RuntimeSceneUtils.GetRootGameObjectsInLoadedScenes()); } }
/// <inheritdoc /> public Scene GetScene(string sceneName) { Scene scene = default(Scene); RuntimeSceneUtils.FindScene(sceneName, out scene, out int sceneIndex); return(scene); }
private static void SceneManagerSceneLoaded(Scene scene, LoadSceneMode loadSceneMode) { if (mixedRealityPlayspace == null) { SearchForAndEnableExistingPlayspace(RuntimeSceneUtils.GetRootGameObjectsInLoadedScenes()); } else { SearchForAndDisableExtraPlayspaces(scene.GetRootGameObjects()); } }
/// <summary> /// Internal method to handles scene unloads /// </summary> private async Task UnloadScenesInternal( IEnumerable <string> scenesToUnload, SceneType sceneType, float progressOffset = 0, float progressTarget = 1, bool sceneOpInProgressWhenFinished = false) { SetSceneOpProgress(true, progressOffset, sceneType); List <string> validNames = new List <string>(); List <int> validIndexes = new List <int>(); foreach (string sceneName in scenesToUnload) { // See if scene exists Scene scene; int sceneIndex; if (!RuntimeSceneUtils.FindScene(sceneName, out scene, out sceneIndex)) { Debug.LogError("Can't unload invalid scene " + sceneName); } else { validIndexes.Add(sceneIndex); validNames.Add(sceneName); } } int totalSceneOps = validIndexes.Count; if (totalSceneOps < 1) { Debug.LogWarning("No valid scenes found to unload."); SetSceneOpProgress(sceneOpInProgressWhenFinished, progressTarget, sceneType); return; } // Invoke our actions InvokeWillUnloadActions(validNames, sceneType); // Unload our scenes if (validIndexes.Count > 0) { List <AsyncOperation> unloadSceneOps = new List <AsyncOperation>(); foreach (int sceneIndex in validIndexes) { Scene scene = SceneManager.GetSceneByBuildIndex(sceneIndex); if (!scene.isLoaded) { continue; } AsyncOperation sceneOp = SceneManager.UnloadSceneAsync(sceneIndex); unloadSceneOps.Add(sceneOp); } // Now wait for all async operations to complete bool completedAllSceneOps = false; float sceneOpProgress = 0; while (!completedAllSceneOps) { if (!Application.isPlaying) { // Break out of this loop if we've stopped playmode return; } completedAllSceneOps = true; sceneOpProgress = 0; for (int i = 0; i < unloadSceneOps.Count; i++) { sceneOpProgress += unloadSceneOps[i].progress; completedAllSceneOps &= unloadSceneOps[i].isDone; } sceneOpProgress = Mathf.Clamp01(SceneOperationProgress / totalSceneOps); SetSceneOpProgress(true, Mathf.Lerp(progressOffset, progressTarget, sceneOpProgress), sceneType); await Task.Yield(); } } // Wait for all scenes to be fully unloaded before proceeding bool scenesUnloaded = false; while (!scenesUnloaded) { if (!Application.isPlaying) { // Break out of this loop if we've stopped playmode return; } scenesUnloaded = true; foreach (int sceneIndex in validIndexes) { Scene scene = SceneManager.GetSceneByBuildIndex(sceneIndex); scenesUnloaded &= !scene.isLoaded; } await Task.Yield(); } // Make sure our content tracker is refreshed contentTracker.RefreshLoadedContent(); // We're done! SetSceneOpProgress(sceneOpInProgressWhenFinished, progressTarget, sceneType); // Invoke our actions InvokeUnloadedActions(validNames, sceneType); }
/// <summary> /// Internal method to handle scene loads /// </summary> private async Task LoadScenesInternal( IEnumerable <string> scenesToLoad, SceneType sceneType, SceneActivationToken activationToken = null, float progressOffset = 0, float progressTarget = 1, bool sceneOpInProgressWhenFinished = false) { // If we're using an activation token let it know that we're NOT ready to proceed activationToken?.SetReadyToProceed(false); SetSceneOpProgress(true, progressOffset, sceneType); // Validate our scenes List <string> validNames = new List <string>(); List <int> validIndexes = new List <int>(); foreach (string sceneName in scenesToLoad) { // See if scene exists Scene scene; int sceneIndex; if (!RuntimeSceneUtils.FindScene(sceneName, out scene, out sceneIndex)) { Debug.LogError("Can't load invalid scene " + sceneName); } else { validIndexes.Add(sceneIndex); validNames.Add(sceneName); } } int totalSceneOps = validIndexes.Count; if (totalSceneOps < 1) { Debug.LogWarning("No valid scenes found to load."); SetSceneOpProgress(sceneOpInProgressWhenFinished, progressTarget, sceneType); return; } // We're about to load scenes - let everyone know InvokeWillLoadActions(validNames, sceneType); // Load our scenes if (validIndexes.Count > 0) { List <AsyncOperation> loadSceneOps = new List <AsyncOperation>(); foreach (int sceneIndex in validIndexes) { Scene scene = SceneManager.GetSceneByBuildIndex(sceneIndex); if (scene.isLoaded) { continue; } AsyncOperation sceneOp = SceneManager.LoadSceneAsync(sceneIndex, LoadSceneMode.Additive); // Set this to true unless we have an activation token sceneOp.allowSceneActivation = (activationToken != null) ? activationToken.AllowSceneActivation : true; loadSceneOps.Add(sceneOp); } // Now wait for all async operations to complete bool completedAllSceneOps = false; while (!completedAllSceneOps) { if (!Application.isPlaying) { // Break out of this loop if we've stopped playmode return; } completedAllSceneOps = true; bool readyToProceed = false; bool allowSceneActivation = (activationToken != null) ? activationToken.AllowSceneActivation : true; // Go through all the load scene ops and see if we're ready to be activated float sceneOpProgress = 0; for (int i = 0; i < loadSceneOps.Count; i++) { // Set allow scene activation // (This can be set to true by user before ReadyToProceed is set) loadSceneOps[i].allowSceneActivation = allowSceneActivation; if (loadSceneOps[i].isDone) { // Sometimes if a scene is small enough, progress will get reset to 0 before you even have a chance to check it // This is true EVEN IF you've set allowSceneActivation to false // So use isDone as a failsafe sceneOpProgress += 1; } else { readyToProceed |= loadSceneOps[i].progress >= SceneActivationLoadProgress; sceneOpProgress += loadSceneOps[i].progress; completedAllSceneOps = false; } } // Let the activation know whether we're ready activationToken?.SetReadyToProceed(readyToProceed); sceneOpProgress = Mathf.Clamp01(SceneOperationProgress / totalSceneOps); SetSceneOpProgress(true, Mathf.Lerp(progressOffset, progressTarget, sceneOpProgress), sceneType); await Task.Yield(); } } // Wait for all scenes to be fully loaded before proceeding bool scenesLoadedAndActivated = false; while (!scenesLoadedAndActivated) { if (!Application.isPlaying) { // Break out of this loop if we've stopped playmode return; } scenesLoadedAndActivated = true; foreach (int sceneIndex in validIndexes) { Scene scene = SceneManager.GetSceneByBuildIndex(sceneIndex); scenesLoadedAndActivated &= (scene.IsValid() & scene.isLoaded); } await Task.Yield(); } // Make sure our content tracker is refreshed contentTracker.RefreshLoadedContent(); // We're done! SetSceneOpProgress(sceneOpInProgressWhenFinished, progressTarget, sceneType); InvokeLoadedActions(validNames, sceneType); }