blob: 74e5a58c3634c142c7c887701f2176259e5e8c1e (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class FragmentManager : MonoBehaviour
{
private static readonly HashSet<string> LoadedSceneNames = new();
// 关键:在每次进入 Play Mode(且不重启域)时,重置静态集合
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetStaticState()
{
LoadedSceneNames.Clear();
// 如果有其他静态字段,也在这里一并重置
}
/// <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)
{
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);
}
}
}
/// <summary>
/// 异步加载场景列表,完成后加入 LoadedSceneNames
/// </summary>
private static void LoadScenes(List<string> 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);
}
}
}
}
|