IEnumerator _SwitchScene(string newScene, IEnumerable <IEnumerableAction> preloadActions)
        {
            SceneRequested(newScene);

            if (asyncLoading)
            {
                yield return(PreloadActions(preloadActions));

                CoreLogger.LogNotice("UnitySceneManager", string.Format("switching to scene {0}", newScene));

                SceneLoadStarted(newScene);

                yield return(Application.LoadLevelAsync(newScene));
            }
            else
            {
                HandlePreloadActions(preloadActions);

                CoreLogger.LogNotice("UnitySceneManager", string.Format("switching to scene {0}", newScene));
                Application.LoadLevel(newScene);

                SceneLoadStarted(newScene);

                yield break;
            }
        }
        override protected IEnumerator Controller()
        {
            ISceneLoaderTask pending = _sceneManager.PendingLoadTask;

            if (pending != null)
            {
                if (pending.SceneName == _sceneName)
                {
                    CoreLogger.LogNotice(LoggerModules.SceneManager, string.Format("{0}: pending request for the same scene ({1}); ending operation", _name, _sceneName));
                    InvokeDone(TaskEnding.Done);
                    yield break;
                }
            }

            CoreLogger.LogDebug(LoggerModules.SceneManager, string.Format("setting pending load to additive loader: {0}", _name));
            _sceneManager.PendingLoadTask = this;

            if (pending != null)
            {
                CoreLogger.LogNotice(LoggerModules.SceneManager, string.Format("{0}: waiting on loader {1}...", _name, pending.Name));
                yield return(GameApplication.Instance.CoroutineFactory.Wait(pending));

                CoreLogger.LogNotice(LoggerModules.SceneManager, string.Format("{0}: waiting on loader {1} done!", _name, pending.Name));
            }

            SceneTransition sceneTransition = null;

            if (_sceneTransition != null)
            {
                sceneTransition = _sceneTransition.gameObject.GetComponent <SceneTransition>();
                if (sceneTransition != null)
                {
                    GameObject newInstance = GameObject.Instantiate(_sceneTransition.gameObject) as GameObject;
                    GameObject.DontDestroyOnLoad(newInstance);

                    sceneTransition = newInstance.GetComponent <SceneTransition>();
                    Debugger.Assert(sceneTransition != null, "sceneTransition cannot be null!");
                    if (sceneTransition != null)
                    {
                        _sceneManager.HookTransition(sceneTransition);
                        GameApplication.Instance.CoroutineFactory.StartCoroutine(sceneTransition.ExitSequence);


                        yield return(GameApplication.Instance.CoroutineFactory.StartCoroutine(sceneTransition.WaitForFadeout));
                    }
                }
            }

            CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("starting additive sync load of scene {0}", _sceneName));
            Application.LoadLevelAdditive(_sceneName);
            CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("done additive load of scene {0}", _sceneName));

            HandleRemovals();

            if (sceneTransition != null)
            {
                sceneTransition.OnLevelWasLoaded(Application.loadedLevel);

                yield return(GameApplication.Instance.CoroutineFactory.StartCoroutine(sceneTransition.WaitForFadein));
            }

            if (_sceneManager.PendingLoadTask == this)
            {
                CoreLogger.LogDebug(LoggerModules.SceneManager, string.Format("resetting pending load from {0} to null", _name));
                _sceneManager.PendingLoadTask = null;
            }

            InvokeDone(TaskEnding.Done);
        }
Пример #3
0
        override protected IEnumerator Controller()
        {
            ISceneLoaderTask pending = _sceneManager.PendingLoadTask;

            if (pending != null)
            {
                if (pending.SceneName == _sceneName)
                {
                    CoreLogger.LogNotice(LoggerModules.SceneManager, string.Format("{0}: pending request for the same scene ({1}); ending operation", _name, _sceneName));
                    InvokeDone(TaskEnding.Done);
                    yield break;
                }
            }

            CoreLogger.LogDebug(LoggerModules.SceneManager, string.Format("setting pending load to {0}", _name));
            _sceneManager.PendingLoadTask = this;

            if (pending != null)
            {
                CoreLogger.LogNotice(LoggerModules.SceneManager, string.Format("{0}: waiting on loader {1}...", _name, pending.Name));
                yield return(GameApplication.Instance.CoroutineFactory.Wait(pending));

                CoreLogger.LogNotice(LoggerModules.SceneManager, string.Format("{0}: waiting on loader {1} done!", _name, pending.Name));
            }

            float startTime = Time.realtimeSinceStartup;

            //check to see if the current scene has a TabTale controller (all scenes are supposed to have one)
            ISceneController currentSceneController = SceneController.Current;

            if (currentSceneController != null)
            {
                if (_sceneTransition != null)
                {
                    if (currentSceneController == null)
                    {
                        CoreLogger.LogNotice(LoggerModules.SceneManager, "no controller found in scene - injection of transitions is not possible!");
                    }
                    else
                    {
                        CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("injecting effect {0} into the scene", _sceneTransition.name));
                        InjectTransition(_sceneTransition, currentSceneController);
                    }
                }

                //tell the current scene it is about to be unloaded
                currentSceneController.PrepareToUnload();

                CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("{0}: waiting for current scene {1} to be ready to unload", _name, currentSceneController.SceneName));

                //async. waiting for either the old scene's signal that it's ready, or the timeout

                while (!currentSceneController.ReadyToUnload && (Time.realtimeSinceStartup - startTime <= _sceneManager.sceneUnloadTimeout))
                {
                    yield return(null);
                }

                CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("scene {0} done - wait took {1} seconds", currentSceneController.SceneName, Time.realtimeSinceStartup - startTime));

                //tell the current scene it is being unloaded
                currentSceneController.OnSceneClosing();
            }
            else
            {
                CoreLogger.LogWarning(LoggerModules.SceneManager, "Unable to find TabTale Scene Controller!");
            }

            _levelLoadStart      = Time.realtimeSinceStartup;
            _levelLoadStartFrame = Time.frameCount;

            if (_sceneManager.asyncPreloading)
            {
                yield return(_sceneManager.PreloadActions(_preloadActions));
            }
            else
            {
                _sceneManager.HandlePreloadActions(_preloadActions);
            }

            if (_sceneManager.asyncLoading && !Application.platform.IsEditor())
            {
                CoreLogger.LogDebug(LoggerModules.SceneManager, string.Format("Loading new scene {0} asynchronously...", _sceneName));

                SceneLoadStarted();

                _asyncLoadOperation = Application.LoadLevelAsync(_sceneName);
                yield return(_asyncLoadOperation);

                _asyncLoadOperation = null;
            }
            else
            {
                //start loading the new scene - note that even though this is a blocking call,
                //it actually starts a background thing, and from this moment on everything
                //is in Limbo
                Application.LoadLevel(_sceneName);
                _progress = 1;

                CoreLogger.LogDebug(LoggerModules.SceneManager, string.Format("Loading new scene {0} synchronously...", _sceneName));

                yield return(new WaitForEndOfFrame());

                yield return(new WaitForEndOfFrame());

                SceneLoadStarted();
            }

            GameApplication.Instance.ApplicationEvents.LevelLoaded -= OnLevelLoaded;

            if (_sceneManager.PendingLoadTask == this)
            {
                CoreLogger.LogDebug(LoggerModules.SceneManager, string.Format("resetting pending load from {0} to null", _name));
                _sceneManager.PendingLoadTask = null;
            }
        }
        override protected IEnumerator Controller()
        {
            ISceneLoaderTask pending = _sceneManager.PendingLoadTask;

            if (pending != null)
            {
                if (pending.SceneName == _sceneName)
                {
                    CoreLogger.LogNotice(LoggerModules.SceneManager, string.Format("{0}: pending request for the same scene ({1}); ending operation", _name, _sceneName));
                    InvokeDone(TaskEnding.Done);
                    yield break;
                }
            }

            CoreLogger.LogDebug(LoggerModules.SceneManager, string.Format("setting pending load to additive loader: {0}", _name));
            _sceneManager.PendingLoadTask = this;

            if (pending != null)
            {
                CoreLogger.LogNotice(LoggerModules.SceneManager, string.Format("{0}: waiting on loader {1}...", _name, pending.Name));
                yield return(GameApplication.Instance.CoroutineFactory.Wait(pending));

                CoreLogger.LogNotice(LoggerModules.SceneManager, string.Format("{0}: waiting on loader {1} done!", _name, pending.Name));
            }

            CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("starting additive async load of scene {0}", _sceneName));
            _operation = Application.LoadLevelAdditiveAsync(_sceneName);
            _operation.allowSceneActivation = false;
            _operation.priority             = 0;

            while (_progress < _additiveLoaderWatermark)
            {
                if (_cancel)
                {
                    InvokeDone(TaskEnding.Cancelled);
                    yield break;
                }

                yield return(null);

                _lastProgress = _progress;
                _progress     = _operation.progress;

                if (_progress < _lastProgress)
                {
                    //time travel - this can happen if we came back from background
                    CoreLogger.LogNotice(LoggerModules.SceneManager, "time travel in scene loader - loading the next scene and calling done");
                }
            }

            _progress = 1;
            yield return(null);

            yield return(new WaitForSeconds(_delay));

            SceneTransition sceneTransition = null;

            if (_sceneTransition != null)
            {
                sceneTransition = _sceneTransition.gameObject.GetComponent <SceneTransition>();
                if (sceneTransition != null)
                {
                    GameObject newInstance = GameObject.Instantiate(_sceneTransition.gameObject) as GameObject;
                    GameObject.DontDestroyOnLoad(newInstance);

                    sceneTransition = newInstance.GetComponent <SceneTransition>();
                    Debugger.Assert(sceneTransition != null, "sceneTransition cannot be null!");
                    if (sceneTransition != null)
                    {
                        GameApplication.Instance.CoroutineFactory.StartCoroutine(sceneTransition.ExitSequence);

                        yield return(GameApplication.Instance.CoroutineFactory.StartCoroutine(sceneTransition.WaitForFadeout));
                    }
                }
            }

            CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("allowing scene additive load operation to complete"));

            _operation.allowSceneActivation = true;
            yield return(_operation);

            CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("done additive load of scene {0}", _sceneName));

            HandleRemovals();

            if (sceneTransition != null)
            {
                sceneTransition.OnLevelWasLoaded(Application.loadedLevel);
                CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("additive load of scene {0} will now handle transition {1}", _sceneName, sceneTransition.name));
                yield return(GameApplication.Instance.CoroutineFactory.StartCoroutine(sceneTransition.WaitForFadein));
            }

            if (_sceneManager.PendingLoadTask == this)
            {
                CoreLogger.LogDebug(LoggerModules.SceneManager, string.Format("resetting pending load from {0} to null", _name));
                _sceneManager.PendingLoadTask = null;
            }
            else
            {
                if (_sceneManager.PendingLoadTask == null)
                {
                    CoreLogger.LogError(LoggerModules.SceneManager, string.Format("{0}: pending load is null!", _name));
                }
                else
                {
                    CoreLogger.LogError(LoggerModules.SceneManager, string.Format("{0}: no need to reset pending since it is already somebody else: {1}", _name, _sceneManager.PendingLoadTask.Name));
                }
            }

            CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("additive load of scene {0} will now invoke done", _sceneName));
            InvokeDone(TaskEnding.Done);
            CoreLogger.LogInfo(LoggerModules.SceneManager, string.Format("additive load of scene {0} has invoked done", _sceneName));
        }