private static void SceneManagerSceneUnloaded(Scene scene)
 {
     if (mixedRealityPlayspace == null)
     {   // If we unloaded our playspace, see if another one exists
         SearchForAndEnableExistingPlayspace(RuntimeSceneUtils.GetRootGameObjectsInLoadedScenes());
     }
 }
Exemplo n.º 2
0
        /// <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);
        }