/// <summary> /// 保存当前关卡切换过程中要使用的各个控制器。 /// </summary> /// <param name="blackScreen">黑屏控制器。</param> /// <param name="asyncer">异步加载控制器。</param> /// <param name="inFader">淡入控制器。</param> private void StoreProcessors(ASceneBlackScreenProcessor blackScreen, AAsyncProcessor asyncer, ASceneFadeInProcessor inFader) { currentBlackScreenProcessor = blackScreen; currentAsyncer = asyncer; currentInFader = inFader; }
/// <summary> /// 切换到指定关卡,限定 Async + Single 模式。 /// </summary> /// <param name="nextMap">目标关卡。</param> /// <param name="outFader">淡出控制器。</par /// am> /// <param name="blackScreen">黑屏阶段控制器。</param> /// <param name="inFader">淡入控制器。</param> /// <param name="asyncer">异步加载控制器。</param> public static void SwitchToLevelAsync(ALevelMap nextMap, ASceneFadeOutProcessor outFader = null, ASceneBlackScreenProcessor blackScreen = null, ASceneFadeInProcessor inFader = null, AAsyncProcessor asyncer = null) { Instance.DoSwitchToLevel(nextMap, outFader, blackScreen, inFader, asyncer, true); }
/// <summary> /// 异步加载迭代器。 /// </summary> private IEnumerator LoadLevelAsyncCoroutine(ALevelMap map, LoadMode mode, AAsyncProcessor asyncer) { if (asyncer != null) { asyncer.StartProgress(map); } LoadSceneMode loadMode = mode == LoadMode.Additive ? LoadSceneMode.Additive : LoadSceneMode.Single; AsyncOperation asyncOp = SceneManager.LoadSceneAsync(map.SceneName, loadMode); // 没有 asyncer 时设置为 true,反之设置为 asyncer.AllowSceneActivation asyncOp.allowSceneActivation = asyncer == null || asyncer.AllowLevelActivation; float progress = 0; while (!asyncOp.isDone) { if (asyncer == null) { yield return(null); continue; } // 注意奇怪的地方: // 1. 当下一个场景很小,且没有 print(""),暂停前输出的 progress 是 0。 // 2. 当下一个场景很小,有 print(""),暂停前输出的 progress 是 0.9。 // 3. 当下一个场景很大,没有 print(""),暂停前输出的 progress 是 0.9,且前面有一大串正确的递增过程。 // 4. 这里注意,大量加载同一个 model 即可获得漂亮的 progress。 // print(""); asyncer.UpdateProgress(asyncOp.progress, map); // AllowSceneActivation 在 PromptToActivate 中设置为 true asyncOp.allowSceneActivation = asyncer.AllowLevelActivation; // 非自动激活场景,第一次到达 0.9 时启动提示激活场景的方法 if (!asyncOp.allowSceneActivation && asyncOp.progress >= 0.9f && progress < 0.9f) { if (LoadLevelPaused != null) { LoadLevelPaused(map, mode); } asyncer.PromptToActivate(map); } progress = asyncOp.progress; yield return(null); } yield return(null); }
/// <summary> /// 异步加载关卡。 /// </summary> /// <param name="map">待加载的关卡。</param> /// <param name="mode">加载模式。</param> /// <param name="asyncer">异步加载控制器。</param> private void DoLoadLevelAsync(ALevelMap map, LoadMode mode, AAsyncProcessor asyncer) { map.ReferencedLevel = ActiveLevel; StoreLoadingLevelMap(map); if (WillLoadLevel != null) { WillLoadLevel(map, mode); } if (StartLoadLevel != null) { StartLoadLevel(map, mode); } StartCoroutine(LoadLevelAsyncCoroutine(map, mode, asyncer)); }
/// <summary> /// 切换到指定关卡,限定 Single 模式。 /// </summary> /// <param name="nextMap">目标关卡。</param> /// <param name="outFader">淡出控制器。</param> /// <param name="blackScreen">黑屏阶段控制器。</param> /// <param name="inFader">淡入控制器。</param> /// <param name="asyncer">异步加载控制器。</param> /// <param name="async">是否异步加载。</param> private void DoSwitchToLevel(ALevelMap nextMap, ASceneFadeOutProcessor outFader, ASceneBlackScreenProcessor blackScreen, ASceneFadeInProcessor inFader, AAsyncProcessor asyncer, bool async) { Assert.IsNotNull(nextMap); if (isSwitching) { Debug.LogError("LevelTransition is in switching"); return; } isSwitching = true; ManuallyFadeIn = false; StoreProcessors(blackScreen, asyncer, inFader); isAsyncSwitching = async; if (outFader != null) { DoFadeOut(nextMap, outFader); return; // 流程转入 FadeOutCompletedCallback } if (blackScreen != null) { DoProcessBlackScreen(nextMap, blackScreen); return; // 流程转入 BlackScreenCompletedCallback } if (async) { DoLoadLevelAsync(nextMap, LoadMode.Single, asyncer); } else { DoLoadLevel(nextMap, LoadMode.Single); } }
/// <summary> /// 异步加载关卡。 /// </summary> /// <param name="map">待加载的关卡。</param> /// <param name="mode">加载模式。</param> /// <param name="asyncer">异步加载控制器。</param> public static void LoadLevelAsync(ALevelMap map, LoadMode mode = LoadMode.Single, AAsyncProcessor asyncer = null) { Instance.DoLoadLevelAsync(map, mode, asyncer); }