private IEnumerator AppendCore(IObserver <SceneInstance> observer, Scenes?identifier, bool activeOnLoad) { if (!identifier.HasValue) { yield break; } SceneInstance sceneInstance = null; var diagnostics = new TimeDiagnostics(); diagnostics.Begin(TimeDiagnostics.Measure.Append); var loadYield = LoadScene(identifier.Value, LoadSceneMode.Additive).ToYieldInstruction(false); while (!loadYield.IsDone) { yield return(null); } if (loadYield.HasError) { OnLoadError(loadYield.Error, identifier); } if (loadYield.HasResult) { sceneInstance = loadYield.Result; appendSceneInstances.Add(sceneInstance); diagnostics.Finish(TimeDiagnostics.Measure.Append); var additiveTime = diagnostics.GetTime(TimeDiagnostics.Measure.Append); var message = string.Format("{0} ({1:F2}ms)(Additive)", identifier.Value, additiveTime); UnityConsole.Event(ConsoleEventName, ConsoleEventColor, message); if (activeOnLoad) { sceneInstance.Enable(); } } observer.OnNext(sceneInstance); observer.OnCompleted(); }
private IEnumerator AppendCore(IObserver <SceneInstance> observer, Scenes?identifier, bool activeOnLoad) { if (!identifier.HasValue) { yield break; } SceneInstance sceneInstance = null; var diagnostics = new TimeDiagnostics(); diagnostics.Begin(TimeDiagnostics.Measure.Append); var loadYield = LoadScene(identifier.Value, LoadSceneMode.Additive).ToYieldInstruction(); yield return(loadYield); if (loadYield.HasResult) { sceneInstance = loadYield.Result; diagnostics.Finish(TimeDiagnostics.Measure.Append); var additiveTime = diagnostics.GetTime(TimeDiagnostics.Measure.Append); UnityConsole.Event(ConsoleEventName, ConsoleEventColor, "{0} ({1}ms)(Additive)", identifier.Value, additiveTime); } if (activeOnLoad) { sceneInstance.Enable(); } observer.OnNext(sceneInstance); observer.OnCompleted(); }
private IEnumerator TransitionCore <TArgument>(TArgument sceneArgument, LoadSceneMode mode, bool isSceneBack, bool registerHistory) where TArgument : ISceneArgument { if (!sceneArgument.Identifier.HasValue) { yield break; } // プリロード停止. if (preLoadDisposable != null) { preLoadDisposable.Dispose(); preLoadDisposable = null; } TransitionTarget = sceneArgument.Identifier; var prevSceneArgument = currentSceneArgument; currentSceneArgument = sceneArgument; var diagnostics = new TimeDiagnostics(); var prev = current; // 現在のシーンを履歴に残さない場合は、既に登録済みの現在のシーン(history[要素数 - 1])を外す. if (!registerHistory && history.Any()) { history.RemoveAt(history.Count - 1); } //====== Begin Transition ====== diagnostics.Begin(TimeDiagnostics.Measure.Total); yield return(TransitionStart(currentSceneArgument).ToYieldInstruction()); if (prev != null) { //====== Scene Leave ====== diagnostics.Begin(TimeDiagnostics.Measure.Leave); // Leave通知. if (onLeave != null) { onLeave.OnNext(prevSceneArgument); } // 現在のシーンの終了処理を実行. yield return(prev.Instance.LeaveAsync().ToYieldInstruction()); // PlayerPrefsを保存. PlayerPrefs.Save(); // Leave終了通知. if (onLeaveComplete != null) { onLeaveComplete.OnNext(prevSceneArgument); } prev.Disable(); diagnostics.Finish(TimeDiagnostics.Measure.Leave); } //====== Scene Unload ====== // 不要なシーンをアンロード. var unloadScenes = loadedscenes.Values // 遷移先のシーンではない. .Where(x => x.Identifier != TransitionTarget) // SceneBaseクラスが存在しない. .Where(x => UnityUtility.IsNull(x.Instance)) // キャッシュ対象でない. .Where(x => cacheScenes.All(y => y != x)) // 次のシーンのPreload対象ではない. .Where(x => currentSceneArgument.PreLoadScenes.All(y => y != x.Identifier)) .ToArray(); foreach (var unloadScene in unloadScenes) { yield return(UnloadScene(unloadScene).ToYieldInstruction()); if (unloadScene.Identifier.HasValue) { loadedscenes.Remove(unloadScene.Identifier.Value); } } //====== Load Next Scene ====== diagnostics.Begin(TimeDiagnostics.Measure.Load); // 次のシーンを読み込み. var identifier = sceneArgument.Identifier.Value; var sceneInfo = loadedscenes.GetValueOrDefault(identifier); if (sceneInfo == null) { var loadYield = LoadScene(identifier, mode).ToYieldInstruction(); yield return(loadYield); if (!loadYield.HasResult) { yield break; } sceneInfo = loadYield.Result; if (sceneArgument.Cache) { cacheScenes.Enqueue(sceneInfo); } } var scene = sceneInfo.GetScene(); if (!scene.HasValue) { Debug.LogErrorFormat("[ {0} ] : Scene情報の取得に失敗しました.", identifier); yield break; } if (sceneInfo.Instance == null) { Debug.LogErrorFormat("[ {0} ] : SceneBase継承クラスが存在しません.", scene.Value.path); yield break; } SetSceneActive(scene); // 前のシーンからの引数を設定. sceneInfo.Instance.SetArgument(sceneArgument); // 現在のシーンとして登録. current = sceneInfo; // 次のシーンを履歴に登録. // シーン引数を保存する為遷移時に引数と一緒に履歴登録する為、履歴の最後尾は現在のシーンになる. if (current.Instance != null) { history.Add(currentSceneArgument); } // シーン読み込み後にAwake、Startが終わるのを待つ為1フレーム後に処理を再開. yield return(null); diagnostics.Finish(TimeDiagnostics.Measure.Load); //====== Scene Prepare ====== diagnostics.Begin(TimeDiagnostics.Measure.Prepare); // Prepar通知. if (onPrepare != null) { onPrepare.OnNext(currentSceneArgument); } // 次のシーンの準備処理実行. if (current.Instance != null) { yield return(current.Instance.Prepare(isSceneBack).ToYieldInstruction()); } // Prepar終了通知. if (onPrepareComplete != null) { onPrepareComplete.OnNext(currentSceneArgument); } diagnostics.Finish(TimeDiagnostics.Measure.Prepare); //====== Unload PrevScene ====== // キャッシュ対象でない場合はアンロード. if (prevSceneArgument == null || !prevSceneArgument.Cache) { yield return(UnloadScene(prev).ToYieldInstruction()); } //====== Scene Wait ====== // メモリ解放. yield return(CleanUp().ToYieldInstruction()); // 外部処理待機. yield return(Observable.FromMicroCoroutine(() => TransitionWait()).ToYieldInstruction()); // シーンを有効化. sceneInfo.Enable(); // シーン遷移完了. TransitionTarget = null; // シーン遷移終了. yield return(TransitionFinish(currentSceneArgument).ToYieldInstruction()); //====== Scene Enter ====== // Enter通知. if (onEnter != null) { onEnter.OnNext(currentSceneArgument); } // 次のシーンの開始処理実行. if (current.Instance != null) { current.Instance.Enter(isSceneBack); } // Enter終了通知. if (onEnterComplete != null) { onEnterComplete.OnNext(currentSceneArgument); } //====== Report ====== diagnostics.Finish(TimeDiagnostics.Measure.Total); var prevScene = prev.Identifier; var nextScene = current.Identifier; var total = diagnostics.GetTime(TimeDiagnostics.Measure.Total); var detail = diagnostics.BuildDetailText(); UnityConsole.Event(ConsoleEventName, ConsoleEventColor, "{0} → {1} ({2:F2}ms)\n\n{3}", prevScene, nextScene, total, detail); //====== PreLoad ====== preLoadDisposable = PreLoadScene(sceneArgument.PreLoadScenes) .Subscribe(_ => preLoadDisposable = null) .AddTo(Disposable); }