From 7735b716401f630697d5b02910d50dbf8f3416af Mon Sep 17 00:00:00 2001 From: Weicao-CatilGrass <1992414357@qq.com> Date: Sat, 30 May 2026 19:35:16 +0800 Subject: 正在编写动态场景加载 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/FragmentManager.cs | 137 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 Assets/Scripts/FragmentManager.cs (limited to 'Assets/Scripts/FragmentManager.cs') diff --git a/Assets/Scripts/FragmentManager.cs b/Assets/Scripts/FragmentManager.cs new file mode 100644 index 0000000..3bac110 --- /dev/null +++ b/Assets/Scripts/FragmentManager.cs @@ -0,0 +1,137 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.SceneManagement; + +public class FragmentManager : MonoBehaviour +{ + private static readonly HashSet LoadedSceneNames = new(); + + /// + /// 刷新场景需要列表(基于场景名称) + /// + /// 需要的场景名称列表(需与 Build Settings 中的名称一致,不带 .unity 扩展名) + public static void UpdateSceneRequirements(List requiredSceneNames) + { + var toUnload = new List(); + var toLoad = new List(); + + // 需要卸载的:当前已加载但不在 requiredSceneNames 中 + foreach (var loadedName in LoadedSceneNames) + { + if (!requiredSceneNames.Contains(loadedName)) + toUnload.Add(loadedName); + } + + // 需要加载的:requiredSceneNames 中尚未加载的 + foreach (var reqName in requiredSceneNames) + { + if (!LoadedSceneNames.Contains(reqName)) + toLoad.Add(reqName); + } + + UnloadScenes(toUnload); + LoadScenes(toLoad); + } + + /// + /// 重置所有场景(先卸载全部,再重新加载) + /// + public static void ReloadAllScenes() + { + var scenesToReload = new List(LoadedSceneNames); + + // 先卸载所有 + foreach (var sceneName in scenesToReload) + { + var asyncOp = SceneManager.UnloadSceneAsync(sceneName); + if (asyncOp != null) + { + asyncOp.completed += _ => + { + if (LoadedSceneNames.Contains(sceneName)) + LoadedSceneNames.Remove(sceneName); + }; + } + else + { + // 同步卸载后备(已过时,仅用于兼容) + if (SceneManager.UnloadScene(sceneName)) + LoadedSceneNames.Remove(sceneName); + } + } + + // 重新加载(注意:卸载异步,立即加载可能导致短暂重叠,但通常可接受) + foreach (var sceneName in scenesToReload) + { + var asyncOp = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive); + if (asyncOp != null) + { + asyncOp.completed += _ => + { + var scene = SceneManager.GetSceneByName(sceneName); + if (scene.isLoaded && !LoadedSceneNames.Contains(sceneName)) + LoadedSceneNames.Add(sceneName); + }; + } + else + { + // 同步加载后备 + SceneManager.LoadScene(sceneName, LoadSceneMode.Additive); + var scene = SceneManager.GetSceneByName(sceneName); + if (scene.isLoaded && !LoadedSceneNames.Contains(sceneName)) + LoadedSceneNames.Add(sceneName); + } + } + } + + /// + /// 异步卸载场景列表,完成后从 LoadedSceneNames 中移除 + /// + private static void UnloadScenes(List sceneNames) + { + foreach (var sceneName in sceneNames) + { + var asyncOp = SceneManager.UnloadSceneAsync(sceneName); + if (asyncOp != null) + { + asyncOp.completed += _ => + { + if (LoadedSceneNames.Contains(sceneName)) + LoadedSceneNames.Remove(sceneName); + }; + } + else + { + if (SceneManager.UnloadScene(sceneName)) + LoadedSceneNames.Remove(sceneName); + } + } + } + + /// + /// 异步加载场景列表,完成后加入 LoadedSceneNames + /// + private static void LoadScenes(List sceneNames) + { + foreach (var sceneName in sceneNames) + { + var asyncOp = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive); + if (asyncOp != null) + { + asyncOp.completed += _ => + { + var scene = SceneManager.GetSceneByName(sceneName); + if (scene.isLoaded && !LoadedSceneNames.Contains(sceneName)) + LoadedSceneNames.Add(sceneName); + }; + } + else + { + SceneManager.LoadScene(sceneName, LoadSceneMode.Additive); + var scene = SceneManager.GetSceneByName(sceneName); + if (scene.isLoaded && !LoadedSceneNames.Contains(sceneName)) + LoadedSceneNames.Add(sceneName); + } + } + } +} \ No newline at end of file -- cgit