Пример #1
0
        public static async UniTask ForceRequest()
        {
            var sceneCount = SceneManager.sceneCount;

            var tasks = new List <UniTask>();

            for (var i = 0; i < sceneCount; i++)
            {
                var scene = SceneManager.GetSceneAt(i);

                var rootObjects = scene.GetRootGameObjects();

                foreach (var rootObject in rootObjects)
                {
                    var targets = UnityUtility.FindObjectsOfInterface <LocalizeAtlasRequest>(rootObject);

                    foreach (var target in targets)
                    {
                        var task = UniTask.Defer(() => target.RequestAtlas());

                        tasks.Add(task);
                    }
                }
            }

            await UniTask.WhenAll(tasks);
        }
Пример #2
0
        private IEnumerator RegisterCurrentSceneCore()
        {
            if (current != null)
            {
                yield break;
            }

            var scene = SceneManager.GetSceneAt(0);

            while (!scene.isLoaded)
            {
                yield return(null);
            }

            var definition = ScenePaths.FirstOrDefault(x => x.Value == scene.path);
            var identifier = definition.Equals(default(KeyValuePair <Scenes, string>)) ? null : (Scenes?)definition.Key;

            var sceneInstance = UnityUtility.FindObjectsOfInterface <ISceneBase>().FirstOrDefault();

            CollectUniqueComponents(scene.GetRootGameObjects());

            if (sceneInstance != null)
            {
                current = new SceneInstance(identifier, sceneInstance, SceneManager.GetSceneAt(0));

                // 起動シーンは引数なしで遷移してきたという扱い.
                history.Add(new BootSceneArgument(identifier));
            }

            if (current == null || current.Instance == null)
            {
                Debug.LogError("Current scene not found.");

                yield break;
            }

            yield return(OnRegisterCurrentScene(current).ToYieldInstruction());

            yield return(current.Instance.Prepare(false).ToYieldInstruction());

            current.Instance.Enter(false);
        }
Пример #3
0
        private IEnumerator UnloadSceneCore(SceneInstance sceneInstance)
        {
            var scene = sceneInstance.GetScene();

            if (!scene.HasValue)
            {
                yield break;
            }

            if (SceneManager.sceneCount <= 1)
            {
                yield break;
            }

            UnityAction <Scene> sceneUnloaded = s =>
            {
                if (s.IsValid())
                {
                    if (sceneInstance.Identifier.HasValue)
                    {
                        var identifier = sceneInstance.Identifier.Value;

                        if (loadedscenes.ContainsKey(identifier))
                        {
                            loadedscenes.Remove(identifier);
                        }
                    }

                    if (cacheScenes.Contains(sceneInstance))
                    {
                        cacheScenes.Remove(sceneInstance);
                    }

                    if (onUnloadScene != null)
                    {
                        onUnloadScene.OnNext(sceneInstance);
                    }
                }
            };

            var rootObjects = scene.Value.GetRootGameObjects();

            foreach (var rootObject in rootObjects)
            {
                var targets = UnityUtility.FindObjectsOfInterface <ISceneEvent>(rootObject);

                foreach (var target in targets)
                {
                    yield return(target.OnUnloadSceneAsObservable().ToYieldInstruction());
                }
            }

            AsyncOperation op = null;

            try
            {
                SceneManager.sceneUnloaded += sceneUnloaded;

                op = SceneManager.UnloadSceneAsync(scene.Value);
            }
            catch (Exception e)
            {
                SceneManager.sceneUnloaded -= sceneUnloaded;

                Debug.LogException(e);

                if (onUnloadError != null)
                {
                    onUnloadError.OnNext(Unit.Default);
                }

                yield break;
            }

            while (!op.isDone)
            {
                yield return(op);
            }

            SceneManager.sceneUnloaded -= sceneUnloaded;

            if (onUnloadSceneComplete != null)
            {
                onUnloadSceneComplete.OnNext(sceneInstance);
            }
        }
Пример #4
0
        private IEnumerator LoadSceneCore(IObserver <SceneInstance> observer, Scenes identifier, LoadSceneMode mode)
        {
            var sceneInstance = loadedscenes.GetValueOrDefault(identifier);

            if (sceneInstance == null)
            {
                var scenePath = ScenePaths.GetValueOrDefault(identifier);

                UnityAction <Scene, LoadSceneMode> sceneLoaded = (s, m) =>
                {
                    if (s.IsValid())
                    {
                        sceneInstance = new SceneInstance(identifier, FindSceneObject(s), s);

                        switch (m)
                        {
                        case LoadSceneMode.Single:
                            loadedscenes.Clear();
                            cacheScenes.Clear();
                            break;
                        }

                        // 初期状態は非アクティブ.
                        sceneInstance.Disable();

                        if (onLoadScene != null)
                        {
                            onLoadScene.OnNext(sceneInstance);
                        }
                    }
                };

                SetEnabledForCapturedComponents(false);

                SceneManager.sceneLoaded += sceneLoaded;

                AsyncOperation op = null;

                try
                {
                    op = SceneManager.LoadSceneAsync(scenePath, mode);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);

                    SceneManager.sceneLoaded -= sceneLoaded;

                    if (onLoadError != null)
                    {
                        onLoadError.OnNext(Unit.Default);
                    }

                    observer.OnError(e);

                    yield break;
                }

                while (!op.isDone)
                {
                    yield return(op);
                }

                SceneManager.sceneLoaded -= sceneLoaded;

                var scene = sceneInstance.GetScene();

                if (scene.HasValue)
                {
                    var rootObjects = scene.Value.GetRootGameObjects();

                    // UniqueComponentsを回収.
                    CollectUniqueComponents(rootObjects);

                    loadedscenes.Add(identifier, sceneInstance);

                    yield return(new WaitForEndOfFrame());

                    if (onLoadSceneComplete != null)
                    {
                        onLoadSceneComplete.OnNext(sceneInstance);
                    }

                    // ISceneEvent発行.
                    foreach (var rootObject in rootObjects)
                    {
                        var targets = UnityUtility.FindObjectsOfInterface <ISceneEvent>(rootObject);

                        foreach (var target in targets)
                        {
                            yield return(target.OnLoadSceneAsObservable().ToYieldInstruction());
                        }
                    }
                }

                SetEnabledForCapturedComponents(true);

                // シーンの初期化処理.
                if (sceneInstance.Instance != null)
                {
                    yield return(sceneInstance.Instance.Initialize().ToYieldInstruction());
                }
            }
            else
            {
                // 初期状態は非アクティブ.
                sceneInstance.Disable();
            }

            observer.OnNext(sceneInstance);
            observer.OnCompleted();
        }
Пример #5
0
        public async UniTask RegisterCurrentScene(ISceneArgument sceneArgument)
        {
            if (currentScene != null)
            {
                return;
            }

            var scene = SceneManager.GetSceneAt(0);

            while (!scene.isLoaded)
            {
                await UniTask.DelayFrame(1);
            }

            var definition = ScenePaths.FirstOrDefault(x => x.Value == scene.path);
            var identifier = definition.Equals(default(KeyValuePair <Scenes, string>)) ? null : (Scenes?)definition.Key;

            var sceneInstance = UnityUtility.FindObjectsOfInterface <ISceneBase>().FirstOrDefault();

            CollectUniqueComponents(scene.GetRootGameObjects());

            if (sceneInstance != null)
            {
                currentScene = new SceneInstance(identifier, sceneInstance, SceneManager.GetSceneAt(0));
            }

            if (currentScene == null || currentScene.Instance == null)
            {
                Debug.LogError("Current scene not found.");

                return;
            }

            currentScene.Instance.SetArgument(sceneArgument);

            await OnRegisterCurrentScene(currentScene);

            history.Add(sceneArgument);

            // ISceneEvent.

            var tasks = new List <UniTask>();

            var rootObjects = scene.GetRootGameObjects();

            foreach (var rootObject in rootObjects)
            {
                var targets = UnityUtility.FindObjectsOfInterface <ISceneEvent>(rootObject);

                foreach (var target in targets)
                {
                    var task = UniTask.Defer(() => target.OnLoadScene());

                    tasks.Add(task);
                }
            }

            await UniTask.WhenAll(tasks);

            // Initialize.

            await currentScene.Instance.Initialize();

            // Prepare.

            if (onPrepare != null)
            {
                onPrepare.OnNext(sceneArgument);
            }

            await currentScene.Instance.Prepare(false);

            if (onPrepareComplete != null)
            {
                onPrepareComplete.OnNext(sceneArgument);
            }

            // Enter.

            if (onEnter != null)
            {
                onEnter.OnNext(sceneArgument);
            }

            currentScene.Instance.Enter(false);

            if (onEnterComplete != null)
            {
                onEnterComplete.OnNext(sceneArgument);
            }
        }