diff options
Diffstat (limited to 'Assets/Scripts/FragmentManager.cs')
| -rw-r--r-- | Assets/Scripts/FragmentManager.cs | 137 |
1 files changed, 137 insertions, 0 deletions
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<string> LoadedSceneNames = new(); + + /// <summary> + /// 刷新场景需要列表(基于场景名称) + /// </summary> + /// <param name="requiredSceneNames">需要的场景名称列表(需与 Build Settings 中的名称一致,不带 .unity 扩展名)</param> + public static void UpdateSceneRequirements(List<string> requiredSceneNames) + { + var toUnload = new List<string>(); + var toLoad = new List<string>(); + + // 需要卸载的:当前已加载但不在 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); + } + + /// <summary> + /// 重置所有场景(先卸载全部,再重新加载) + /// </summary> + public static void ReloadAllScenes() + { + var scenesToReload = new List<string>(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); + } + } + } + + /// <summary> + /// 异步卸载场景列表,完成后从 LoadedSceneNames 中移除 + /// </summary> + private static void UnloadScenes(List<string> 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); + } + } + } + + /// <summary> + /// 异步加载场景列表,完成后加入 LoadedSceneNames + /// </summary> + private static void LoadScenes(List<string> 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 |
