using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class FragmentManager : MonoBehaviour { private static readonly HashSet LoadedSceneNames = new(); // 关键:在每次进入 Play Mode(且不重启域)时,重置静态集合 [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void ResetStaticState() { LoadedSceneNames.Clear(); // 如果有其他静态字段,也在这里一并重置 } /// /// 刷新场景需要列表(基于场景名称) /// /// 需要的场景名称列表(需与 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) { Debug.Log("Unloading: " + sceneName); 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) { Debug.Log("Loading: " + sceneName); 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); } } } }