fr.jeanf.scenemanagement 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Runtime/AdditiveLoading/Editor/WorldManagerEditor.cs +83 -0
- package/Runtime/AdditiveLoading/Editor/WorldManagerEditor.cs.meta +2 -0
- package/Runtime/AdditiveLoading/WorldManager.cs +217 -75
- package/Runtime/DynamicLoading/FollowSystem.cs +24 -13
- package/Runtime/DynamicLoading/RegionConnectivity.cs +36 -0
- package/Runtime/DynamicLoading/VolumeSystem.cs +156 -63
- package/Samples/Example/RegionData/Region_00/Region_00.asset +1 -1
- package/Samples/Example/RegionData/Region_01/Region_01.asset +3 -3
- package/Samples/Example/RegionData/Region_02/Region_02.asset +3 -3
- package/Samples/Example/RegionData/Region_02/Zones/Zone_22.asset +1 -1
- package/Samples/Example/RegionData/Region_02/Zones/Zone_23.asset +1 -1
- package/Samples/Example/RegionData/Region_02/Zones/Zone_24.asset +1 -1
- package/Samples/Example/RegionData/Region_02/Zones/Zone_25.asset +1 -1
- package/Samples/Example/RegionData/Region_02/Zones/Zone_26.asset +1 -1
- package/Samples/Example/RegionData/Region_02/Zones/Zone_27.asset +1 -1
- package/Samples/Example/RegionData/Region_02/Zones/Zone_28.asset +1 -1
- package/Samples/Example/Scenes/Main.unity +5 -5
- package/Samples/Setup/AdditiveLoading.prefab +7 -1
- package/package.json +1 -1
- /package/Samples/Example/Scenes/01/{1.unity → 11.unity} +0 -0
- /package/Samples/Example/Scenes/01/{1.unity.meta → 11.unity.meta} +0 -0
- /package/Samples/Example/Scenes/01/{2.unity → 12.unity} +0 -0
- /package/Samples/Example/Scenes/01/{2.unity.meta → 12.unity.meta} +0 -0
- /package/Samples/Example/Scenes/01/{3.unity → 13.unity} +0 -0
- /package/Samples/Example/Scenes/01/{3.unity.meta → 13.unity.meta} +0 -0
- /package/Samples/Example/Scenes/01/{4.unity → 14.unity} +0 -0
- /package/Samples/Example/Scenes/01/{4.unity.meta → 14.unity.meta} +0 -0
- /package/Samples/Example/Scenes/01/{5.unity → 15.unity} +0 -0
- /package/Samples/Example/Scenes/01/{5.unity.meta → 15.unity.meta} +0 -0
- /package/Samples/Example/Scenes/01/{6.unity → 16.unity} +0 -0
- /package/Samples/Example/Scenes/01/{6.unity.meta → 16.unity.meta} +0 -0
- /package/Samples/Example/Scenes/01/{7.unity → 17.unity} +0 -0
- /package/Samples/Example/Scenes/01/{7.unity.meta → 17.unity.meta} +0 -0
- /package/Samples/Example/Scenes/01/{8.unity → 18.unity} +0 -0
- /package/Samples/Example/Scenes/01/{8.unity.meta → 18.unity.meta} +0 -0
- /package/Samples/Example/Scenes/02/{1.unity → 21.unity} +0 -0
- /package/Samples/Example/Scenes/02/{1.unity.meta → 21.unity.meta} +0 -0
- /package/Samples/Example/Scenes/02/{2.unity → 22.unity} +0 -0
- /package/Samples/Example/Scenes/02/{2.unity.meta → 22.unity.meta} +0 -0
- /package/Samples/Example/Scenes/02/{3.unity → 23.unity} +0 -0
- /package/Samples/Example/Scenes/02/{3.unity.meta → 23.unity.meta} +0 -0
- /package/Samples/Example/Scenes/02/{4.unity → 24.unity} +0 -0
- /package/Samples/Example/Scenes/02/{4.unity.meta → 24.unity.meta} +0 -0
- /package/Samples/Example/Scenes/02/{5.unity → 25.unity} +0 -0
- /package/Samples/Example/Scenes/02/{5.unity.meta → 25.unity.meta} +0 -0
- /package/Samples/Example/Scenes/02/{6.unity → 26.unity} +0 -0
- /package/Samples/Example/Scenes/02/{6.unity.meta → 26.unity.meta} +0 -0
- /package/Samples/Example/Scenes/02/{7.unity → 27.unity} +0 -0
- /package/Samples/Example/Scenes/02/{7.unity.meta → 27.unity.meta} +0 -0
- /package/Samples/Example/Scenes/02/{8.unity → 28.unity} +0 -0
- /package/Samples/Example/Scenes/02/{8.unity.meta → 28.unity.meta} +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#if UNITY_EDITOR
|
|
2
|
+
using UnityEngine;
|
|
3
|
+
using UnityEditor;
|
|
4
|
+
|
|
5
|
+
namespace jeanf.scenemanagement
|
|
6
|
+
{
|
|
7
|
+
[CustomEditor(typeof(WorldManager))]
|
|
8
|
+
public class WorldManagerEditor : Editor
|
|
9
|
+
{
|
|
10
|
+
public override void OnInspectorGUI()
|
|
11
|
+
{
|
|
12
|
+
DrawDefaultInspector();
|
|
13
|
+
|
|
14
|
+
var worldManager = (WorldManager)target;
|
|
15
|
+
|
|
16
|
+
EditorGUILayout.Space();
|
|
17
|
+
EditorGUILayout.LabelField("Current Player State", EditorStyles.boldLabel);
|
|
18
|
+
|
|
19
|
+
var currentZone = WorldManager.CurrentPlayerZone;
|
|
20
|
+
var currentRegion = WorldManager.CurrentPlayerRegion;
|
|
21
|
+
|
|
22
|
+
EditorGUI.BeginDisabledGroup(true);
|
|
23
|
+
|
|
24
|
+
if (currentZone != null)
|
|
25
|
+
{
|
|
26
|
+
EditorGUILayout.TextField("Current Zone", $"{currentZone.zoneName}");
|
|
27
|
+
}
|
|
28
|
+
else
|
|
29
|
+
{
|
|
30
|
+
EditorGUILayout.TextField("Current Zone", "None");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (currentRegion != null)
|
|
34
|
+
{
|
|
35
|
+
EditorGUILayout.TextField("Current Region", $"{currentRegion.levelName}");
|
|
36
|
+
}
|
|
37
|
+
else
|
|
38
|
+
{
|
|
39
|
+
EditorGUILayout.TextField("Current Region", "None");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
EditorGUI.EndDisabledGroup();
|
|
43
|
+
|
|
44
|
+
if (Application.isPlaying)
|
|
45
|
+
{
|
|
46
|
+
EditorGUILayout.Space();
|
|
47
|
+
if (GUILayout.Button("Debug Zone/Region Info"))
|
|
48
|
+
{
|
|
49
|
+
Debug.Log($"=== WorldManager Debug Info ===");
|
|
50
|
+
Debug.Log($"Current Zone: {(currentZone != null ? $"'{currentZone.zoneName}' (ID: {currentZone.id})" : "None")}");
|
|
51
|
+
Debug.Log($"Current Region: {(currentRegion != null ? $"'{currentRegion.levelName}' (ID: {currentRegion.id})" : "None")}");
|
|
52
|
+
|
|
53
|
+
var zoneCount = worldManager.GetType().GetField("_zoneDictionary",
|
|
54
|
+
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
|
|
55
|
+
?.GetValue(worldManager) as System.Collections.Generic.Dictionary<string, Zone>;
|
|
56
|
+
|
|
57
|
+
var regionCount = worldManager.GetType().GetField("_regionDictionary",
|
|
58
|
+
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
|
|
59
|
+
?.GetValue(worldManager) as System.Collections.Generic.Dictionary<string, Region>;
|
|
60
|
+
|
|
61
|
+
if (zoneCount != null && regionCount != null)
|
|
62
|
+
{
|
|
63
|
+
Debug.Log($"Total zones in dictionary: {zoneCount.Count}");
|
|
64
|
+
Debug.Log($"Total regions in dictionary: {regionCount.Count}");
|
|
65
|
+
|
|
66
|
+
Debug.Log("Available zones:");
|
|
67
|
+
foreach (var zone in zoneCount.Values)
|
|
68
|
+
{
|
|
69
|
+
Debug.Log($" - '{zone.zoneName}' (ID: {zone.id})");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
Debug.Log("Available regions:");
|
|
73
|
+
foreach (var region in regionCount.Values)
|
|
74
|
+
{
|
|
75
|
+
Debug.Log($" - '{region.levelName}' (ID: {region.id})");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
#endif
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
using System.Collections.Generic;
|
|
2
|
-
using System.Linq;
|
|
3
2
|
using UnityEngine;
|
|
4
3
|
using jeanf.EventSystem;
|
|
5
4
|
using jeanf.propertyDrawer;
|
|
@@ -14,36 +13,57 @@ namespace jeanf.scenemanagement
|
|
|
14
13
|
public bool isDebug = false;
|
|
15
14
|
private SceneLoader _sceneLoader;
|
|
16
15
|
public List<Region> ListOfRegions;
|
|
16
|
+
|
|
17
17
|
private Dictionary<string, Zone> _zoneDictionary = new Dictionary<string, Zone>();
|
|
18
18
|
private Dictionary<string, Region> _regionDictionary = new Dictionary<string, Region>();
|
|
19
19
|
private Dictionary<string, Region> _regionDictionaryPerZone = new Dictionary<string, Region>();
|
|
20
|
-
private Dictionary<Collider, Region> _regionDictionaryPerCollider = new Dictionary<Collider, Region>();
|
|
21
20
|
private Dictionary<string, List<SceneReference>> _dependenciesPerRegion = new Dictionary<string, List<SceneReference>>();
|
|
21
|
+
private Dictionary<string, List<string>> _compiledSceneLists = new Dictionary<string, List<string>>();
|
|
22
|
+
private HashSet<string> _landingZoneIds = new HashSet<string>();
|
|
22
23
|
|
|
23
24
|
private List<Region> _activeRegions = new List<Region>();
|
|
24
|
-
private
|
|
25
|
+
private bool _mappingInitialized = false;
|
|
26
|
+
|
|
27
|
+
private List<string> _tempSceneNames = new List<string>();
|
|
28
|
+
private List<Region> _tempRegionsToRemove = new List<Region>();
|
|
25
29
|
|
|
26
30
|
[SerializeField] private StringEventChannelSO regionChangeRequestChannel;
|
|
27
31
|
[SerializeField] private SendTeleportTarget sendTeleportTarget;
|
|
28
32
|
|
|
29
33
|
[ReadOnly] [SerializeField] private Zone _currentPlayerZone;
|
|
34
|
+
[ReadOnly] [SerializeField] private Region _currentPlayerRegion;
|
|
35
|
+
|
|
30
36
|
private static WorldManager Instance;
|
|
37
|
+
private static bool _isRegionTransitioning = false;
|
|
38
|
+
|
|
31
39
|
public static Zone CurrentPlayerZone
|
|
32
40
|
{
|
|
33
|
-
get => Instance
|
|
34
|
-
private set
|
|
41
|
+
get => Instance?._currentPlayerZone;
|
|
42
|
+
private set
|
|
43
|
+
{
|
|
44
|
+
if (Instance != null)
|
|
45
|
+
{
|
|
46
|
+
Instance._currentPlayerZone = value;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
35
49
|
}
|
|
36
50
|
|
|
37
|
-
[ReadOnly] [SerializeField] private Region _currentPlayerRegion;
|
|
38
51
|
public static Region CurrentPlayerRegion
|
|
39
52
|
{
|
|
40
|
-
get => Instance
|
|
41
|
-
private set
|
|
53
|
+
get => Instance?._currentPlayerRegion;
|
|
54
|
+
private set
|
|
55
|
+
{
|
|
56
|
+
if (Instance != null)
|
|
57
|
+
{
|
|
58
|
+
Instance._currentPlayerRegion = value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
42
61
|
}
|
|
43
62
|
|
|
63
|
+
public static bool IsRegionTransitioning => _isRegionTransitioning;
|
|
64
|
+
|
|
44
65
|
public delegate void SendId(string newRegionID);
|
|
45
66
|
public static SendId RequestRegionChange;
|
|
46
|
-
|
|
47
67
|
public static SendId PublishCurrentRegionId;
|
|
48
68
|
public static SendId PublishCurrentZoneId;
|
|
49
69
|
|
|
@@ -54,7 +74,8 @@ namespace jeanf.scenemanagement
|
|
|
54
74
|
public static BroadcastAppList _broadcastAppList;
|
|
55
75
|
|
|
56
76
|
private bool hasGameBeenInitialized = false;
|
|
57
|
-
|
|
77
|
+
private string _lastNotifiedZone = "";
|
|
78
|
+
private string _lastNotifiedRegion = "";
|
|
58
79
|
|
|
59
80
|
private void Awake()
|
|
60
81
|
{
|
|
@@ -71,7 +92,6 @@ namespace jeanf.scenemanagement
|
|
|
71
92
|
{
|
|
72
93
|
regionChangeRequestChannel.OnEventRaised += OnRegionChange;
|
|
73
94
|
RequestRegionChange += OnRegionChange;
|
|
74
|
-
|
|
75
95
|
ResetWorld += Init;
|
|
76
96
|
ScenarioManager.OnZoneOverridesChanged += OnZoneOverridesChanged;
|
|
77
97
|
}
|
|
@@ -80,112 +100,214 @@ namespace jeanf.scenemanagement
|
|
|
80
100
|
{
|
|
81
101
|
regionChangeRequestChannel.OnEventRaised -= OnRegionChange;
|
|
82
102
|
RequestRegionChange -= OnRegionChange;
|
|
83
|
-
|
|
84
103
|
ResetWorld -= Init;
|
|
85
104
|
ScenarioManager.OnZoneOverridesChanged -= OnZoneOverridesChanged;
|
|
86
105
|
}
|
|
87
106
|
|
|
88
|
-
|
|
89
107
|
private void Init()
|
|
90
108
|
{
|
|
91
|
-
if(isDebug) Debug.Log($"[WorldManager] World reset.");
|
|
92
109
|
hasGameBeenInitialized = false;
|
|
110
|
+
_currentPlayerZone = null;
|
|
111
|
+
_currentPlayerRegion = null;
|
|
112
|
+
_lastNotifiedZone = "";
|
|
113
|
+
_lastNotifiedRegion = "";
|
|
114
|
+
_isRegionTransitioning = false;
|
|
115
|
+
|
|
116
|
+
ClearAllMappings();
|
|
117
|
+
BuildDataMappings();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private void ClearAllMappings()
|
|
121
|
+
{
|
|
122
|
+
_zoneDictionary.Clear();
|
|
123
|
+
_regionDictionary.Clear();
|
|
124
|
+
_regionDictionaryPerZone.Clear();
|
|
125
|
+
_dependenciesPerRegion.Clear();
|
|
126
|
+
_compiledSceneLists.Clear();
|
|
127
|
+
_landingZoneIds.Clear();
|
|
128
|
+
_activeRegions.Clear();
|
|
129
|
+
_tempSceneNames.Clear();
|
|
130
|
+
_tempRegionsToRemove.Clear();
|
|
131
|
+
_mappingInitialized = false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private void BuildDataMappings()
|
|
135
|
+
{
|
|
136
|
+
if (_mappingInitialized) return;
|
|
137
|
+
|
|
138
|
+
var regionCount = ListOfRegions?.Count ?? 0;
|
|
139
|
+
if (regionCount == 0) return;
|
|
140
|
+
|
|
93
141
|
foreach (var region in ListOfRegions)
|
|
94
142
|
{
|
|
95
|
-
|
|
96
|
-
if(
|
|
97
|
-
|
|
143
|
+
if (region == null) continue;
|
|
144
|
+
if (!_regionDictionary.TryAdd(region.id, region)) continue;
|
|
145
|
+
|
|
146
|
+
_dependenciesPerRegion.TryAdd(region.id, region.dependenciesInThisRegion);
|
|
147
|
+
PrecompileSceneList(region);
|
|
98
148
|
|
|
99
|
-
|
|
100
|
-
foreach (var scenario in region.scenariosInThisRegion)
|
|
149
|
+
if (region.scenariosInThisRegion != null)
|
|
101
150
|
{
|
|
102
|
-
|
|
103
|
-
|
|
151
|
+
foreach (var scenario in region.scenariosInThisRegion)
|
|
152
|
+
{
|
|
153
|
+
if (scenario != null)
|
|
154
|
+
{
|
|
155
|
+
ScenarioManager.ScenarioDictionary.TryAdd(scenario.id, scenario);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
104
158
|
}
|
|
105
159
|
|
|
106
|
-
|
|
107
|
-
foreach (var zone in region.zonesInThisRegion)
|
|
160
|
+
if (region.zonesInThisRegion != null)
|
|
108
161
|
{
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
162
|
+
foreach (var zone in region.zonesInThisRegion)
|
|
163
|
+
{
|
|
164
|
+
if (zone != null)
|
|
165
|
+
{
|
|
166
|
+
_zoneDictionary.TryAdd(zone.id, zone);
|
|
167
|
+
_regionDictionaryPerZone.TryAdd(zone.id, region);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
BuildLandingZoneCache();
|
|
174
|
+
_mappingInitialized = true;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private void PrecompileSceneList(Region region)
|
|
178
|
+
{
|
|
179
|
+
var sceneNames = new List<string>(region.dependenciesInThisRegion.Count);
|
|
180
|
+
foreach (var dependency in region.dependenciesInThisRegion)
|
|
181
|
+
{
|
|
182
|
+
sceneNames.Add(dependency.SceneName);
|
|
183
|
+
}
|
|
184
|
+
_compiledSceneLists[region.id] = sceneNames;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private void BuildLandingZoneCache()
|
|
188
|
+
{
|
|
189
|
+
var connectivity = FindObjectOfType<RegionConnectivityAuthoring>();
|
|
190
|
+
if (connectivity?.regionConnectivity?.landingZones == null) return;
|
|
191
|
+
|
|
192
|
+
foreach (var landing in connectivity.regionConnectivity.landingZones)
|
|
193
|
+
{
|
|
194
|
+
if (landing?.landingZone != null)
|
|
195
|
+
{
|
|
196
|
+
_landingZoneIds.Add(landing.landingZone.id);
|
|
197
|
+
}
|
|
117
198
|
}
|
|
118
199
|
}
|
|
119
200
|
|
|
120
201
|
public static void NotifyZoneChangeFromECS(string zoneId)
|
|
121
202
|
{
|
|
122
|
-
if (Instance != null)
|
|
203
|
+
if (Instance != null && !_isRegionTransitioning)
|
|
123
204
|
{
|
|
124
205
|
Instance.OnZoneChangedFromECS(zoneId);
|
|
125
206
|
}
|
|
126
207
|
}
|
|
208
|
+
|
|
209
|
+
public static void NotifyRegionChangeFromECS(string regionId)
|
|
210
|
+
{
|
|
211
|
+
if (Instance != null && !_isRegionTransitioning)
|
|
212
|
+
{
|
|
213
|
+
Instance.OnRegionChangedFromECS(regionId);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
127
216
|
|
|
128
217
|
private void OnZoneChangedFromECS(string zoneId)
|
|
129
218
|
{
|
|
219
|
+
if (string.IsNullOrEmpty(zoneId) || _lastNotifiedZone == zoneId) return;
|
|
220
|
+
|
|
130
221
|
if (!_zoneDictionary.TryGetValue(zoneId, out var zone)) return;
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
222
|
+
|
|
223
|
+
_lastNotifiedZone = zoneId;
|
|
224
|
+
_currentPlayerZone = zone;
|
|
225
|
+
|
|
226
|
+
PublishCurrentZoneId?.Invoke(zone.id);
|
|
134
227
|
PublishAppList(zone);
|
|
135
|
-
|
|
136
|
-
var newRegion = _regionDictionaryPerZone[zone.id.id];
|
|
137
|
-
if(newRegion != CurrentPlayerRegion) OnRegionChange(newRegion);
|
|
138
228
|
}
|
|
229
|
+
|
|
230
|
+
private void OnRegionChangedFromECS(string regionId)
|
|
231
|
+
{
|
|
232
|
+
if (string.IsNullOrEmpty(regionId) || _lastNotifiedRegion == regionId) return;
|
|
233
|
+
|
|
234
|
+
if (!_regionDictionary.TryGetValue(regionId, out var region)) return;
|
|
235
|
+
|
|
236
|
+
_lastNotifiedRegion = regionId;
|
|
237
|
+
_currentPlayerRegion = region;
|
|
238
|
+
|
|
239
|
+
OnRegionChange(region);
|
|
240
|
+
}
|
|
241
|
+
|
|
139
242
|
private void OnZoneOverridesChanged(string zoneId)
|
|
140
243
|
{
|
|
141
|
-
|
|
142
|
-
if (CurrentPlayerZone.id == zoneId)
|
|
244
|
+
if (CurrentPlayerZone != null && CurrentPlayerZone.id == zoneId)
|
|
143
245
|
{
|
|
144
246
|
PublishAppList(CurrentPlayerZone);
|
|
145
247
|
}
|
|
146
248
|
}
|
|
147
249
|
|
|
148
|
-
private void SetCurrentZoneAndRegion(GameObject gameObject, Zone zone)
|
|
149
|
-
{
|
|
150
|
-
if (!gameObject.CompareTag("Player")) return;
|
|
151
|
-
CurrentPlayerZone = zone;
|
|
152
|
-
PublishCurrentZoneId?.Invoke(zone.id);
|
|
153
|
-
PublishAppList(zone);
|
|
154
|
-
var newRegion = _regionDictionaryPerZone[zone.id];
|
|
155
|
-
if(newRegion != CurrentPlayerRegion) OnRegionChange(newRegion);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
250
|
private void OnRegionChange(string newRegionID)
|
|
159
251
|
{
|
|
160
252
|
if (!_regionDictionary.TryGetValue(newRegionID, out var region)) return;
|
|
161
253
|
OnRegionChange(region);
|
|
162
254
|
}
|
|
163
255
|
|
|
164
|
-
// ReSharper disable Unity.PerformanceAnalysis
|
|
165
256
|
private void OnRegionChange(Region region)
|
|
166
257
|
{
|
|
167
|
-
|
|
168
|
-
|
|
258
|
+
_isRegionTransitioning = true;
|
|
259
|
+
|
|
260
|
+
_currentPlayerRegion = region;
|
|
261
|
+
_lastNotifiedRegion = region.id;
|
|
262
|
+
|
|
263
|
+
PublishCurrentRegionId?.Invoke(_currentPlayerRegion.id);
|
|
169
264
|
|
|
170
|
-
|
|
171
|
-
var
|
|
265
|
+
_tempRegionsToRemove.Clear();
|
|
266
|
+
foreach (var activeRegion in _activeRegions)
|
|
267
|
+
{
|
|
268
|
+
var removedRegion = RequestUnLoadForObsoleteRegion(activeRegion);
|
|
269
|
+
_tempRegionsToRemove.Add(removedRegion);
|
|
270
|
+
}
|
|
172
271
|
|
|
173
|
-
foreach (var r in
|
|
272
|
+
foreach (var r in _tempRegionsToRemove)
|
|
174
273
|
{
|
|
175
274
|
_activeRegions.Remove(r);
|
|
176
275
|
}
|
|
177
276
|
|
|
178
277
|
RequestLoadForRegionDependencies(region);
|
|
179
278
|
|
|
180
|
-
// set teleporting position
|
|
181
279
|
var spawnPos = SetTeleportTarget(region, hasGameBeenInitialized);
|
|
182
|
-
sendTeleportTarget.transform.position = spawnPos.position;
|
|
183
|
-
sendTeleportTarget.transform.rotation = Quaternion.Euler(spawnPos.rotation);
|
|
184
|
-
// teleport!
|
|
185
|
-
sendTeleportTarget.Teleport();
|
|
186
280
|
|
|
187
|
-
|
|
281
|
+
if (sendTeleportTarget != null)
|
|
282
|
+
{
|
|
283
|
+
sendTeleportTarget.transform.position = spawnPos.position;
|
|
284
|
+
sendTeleportTarget.transform.rotation = Quaternion.Euler(spawnPos.rotation);
|
|
285
|
+
sendTeleportTarget.Teleport();
|
|
286
|
+
}
|
|
287
|
+
|
|
188
288
|
_activeRegions.Add(region);
|
|
289
|
+
|
|
290
|
+
StartCoroutine(CompleteRegionTransition());
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private System.Collections.IEnumerator CompleteRegionTransition()
|
|
294
|
+
{
|
|
295
|
+
yield return new WaitForEndOfFrame();
|
|
296
|
+
yield return new WaitForEndOfFrame();
|
|
297
|
+
|
|
298
|
+
_isRegionTransitioning = false;
|
|
299
|
+
|
|
300
|
+
if (_currentPlayerRegion?.zonesInThisRegion != null && _currentPlayerRegion.zonesInThisRegion.Count > 0)
|
|
301
|
+
{
|
|
302
|
+
var firstZone = _currentPlayerRegion.zonesInThisRegion[0];
|
|
303
|
+
if (firstZone != null)
|
|
304
|
+
{
|
|
305
|
+
_currentPlayerZone = firstZone;
|
|
306
|
+
_lastNotifiedZone = firstZone.id;
|
|
307
|
+
PublishCurrentZoneId?.Invoke(firstZone.id);
|
|
308
|
+
PublishAppList(firstZone);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
189
311
|
}
|
|
190
312
|
|
|
191
313
|
private SpawnPos SetTeleportTarget(Region region, bool hasRegionBeenInitialized)
|
|
@@ -203,39 +325,59 @@ namespace jeanf.scenemanagement
|
|
|
203
325
|
private void PublishAppList(Zone zone)
|
|
204
326
|
{
|
|
205
327
|
var listToBroadcast = zone.DefaultAppsInZone;
|
|
206
|
-
if(isDebug) Debug.Log($"[WorldManager] Default list for zone [{zone.name}] : [{string.Join(", ", listToBroadcast)}]");
|
|
207
|
-
// check if for this zone there is no override
|
|
208
328
|
if (ScenarioManager.activeOverridesPerZone.TryGetValue(zone.id, out var value))
|
|
209
329
|
{
|
|
210
|
-
// if yes, send override list
|
|
211
330
|
listToBroadcast = value;
|
|
212
|
-
if(isDebug) Debug.Log($"[WorldManager] List override found for zone [{zone.name}] : [{string.Join(", ", listToBroadcast)}]");
|
|
213
331
|
}
|
|
214
332
|
|
|
215
|
-
// broadcast list
|
|
216
333
|
_broadcastAppList?.Invoke(listToBroadcast);
|
|
217
334
|
}
|
|
218
335
|
|
|
219
336
|
private void RequestLoadForRegionDependencies(Region region)
|
|
220
337
|
{
|
|
221
|
-
if (
|
|
222
|
-
|
|
338
|
+
if (!_compiledSceneLists.TryGetValue(region.id, out var sceneNames) || sceneNames.Count <= 0) return;
|
|
339
|
+
|
|
340
|
+
foreach (var sceneName in sceneNames)
|
|
223
341
|
{
|
|
224
|
-
_sceneLoader.LoadSceneRequest(
|
|
342
|
+
_sceneLoader.LoadSceneRequest(sceneName);
|
|
225
343
|
}
|
|
226
344
|
}
|
|
345
|
+
|
|
227
346
|
private Region RequestUnLoadForObsoleteRegion(Region region)
|
|
228
347
|
{
|
|
229
|
-
|
|
348
|
+
if (_compiledSceneLists.TryGetValue(region.id, out var sceneNames))
|
|
230
349
|
{
|
|
231
|
-
|
|
350
|
+
foreach (var sceneName in sceneNames)
|
|
351
|
+
{
|
|
352
|
+
_sceneLoader.UnLoadSceneRequest(sceneName);
|
|
353
|
+
}
|
|
232
354
|
}
|
|
233
355
|
return region;
|
|
234
356
|
}
|
|
235
|
-
|
|
236
|
-
|
|
357
|
+
|
|
358
|
+
public bool IsLandingZone(string zoneId)
|
|
359
|
+
{
|
|
360
|
+
return _landingZoneIds.Contains(zoneId);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
public HashSet<string> GetLandingZoneIds()
|
|
364
|
+
{
|
|
365
|
+
return _landingZoneIds;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
public static Dictionary<string, Zone> GetZoneDictionary()
|
|
369
|
+
{
|
|
370
|
+
return Instance?._zoneDictionary;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
public static Dictionary<string, Region> GetRegionDictionary()
|
|
374
|
+
{
|
|
375
|
+
return Instance?._regionDictionary;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
public static Dictionary<string, Region> GetRegionDictionaryPerZone()
|
|
237
379
|
{
|
|
238
|
-
return
|
|
380
|
+
return Instance?._regionDictionaryPerZone;
|
|
239
381
|
}
|
|
240
382
|
}
|
|
241
383
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
using Unity.Burst;
|
|
2
|
+
using Unity.Collections;
|
|
2
3
|
using Unity.Entities;
|
|
3
4
|
using Unity.Mathematics;
|
|
4
5
|
using Unity.Transforms;
|
|
@@ -9,39 +10,48 @@ namespace jeanf.scenemanagement
|
|
|
9
10
|
[UpdateInGroup(typeof(InitializationSystemGroup))]
|
|
10
11
|
public partial struct FollowSystem : ISystem
|
|
11
12
|
{
|
|
12
|
-
private float3 _currentCameraPosition;
|
|
13
13
|
private float3 _lastCameraPosition;
|
|
14
14
|
private const float MIN_POSITION_CHANGE = 0.1f;
|
|
15
|
+
private const float MIN_POSITION_CHANGE_SQ = MIN_POSITION_CHANGE * MIN_POSITION_CHANGE;
|
|
16
|
+
private bool _isInitialized;
|
|
15
17
|
|
|
16
18
|
[BurstCompile]
|
|
17
19
|
public void OnCreate(ref SystemState state)
|
|
18
20
|
{
|
|
19
21
|
state.RequireForUpdate<FollowComponent>();
|
|
20
22
|
_lastCameraPosition = float3.zero;
|
|
23
|
+
_isInitialized = false;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
public void OnUpdate(ref SystemState state)
|
|
24
27
|
{
|
|
25
28
|
if (Camera.main == null) return;
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
var currentCameraPosition = (float3)Camera.main.transform.position;
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
float distanceSq = math.distancesq(_lastCameraPosition, _currentCameraPosition);
|
|
31
|
-
|
|
32
|
-
if (isFirstUpdate || distanceSq >= MIN_POSITION_CHANGE * MIN_POSITION_CHANGE)
|
|
32
|
+
if (!_isInitialized)
|
|
33
33
|
{
|
|
34
|
-
_lastCameraPosition =
|
|
34
|
+
_lastCameraPosition = currentCameraPosition;
|
|
35
|
+
_isInitialized = true;
|
|
35
36
|
|
|
36
|
-
new FollowJob
|
|
37
|
+
state.Dependency = new FollowJob
|
|
37
38
|
{
|
|
38
|
-
CameraPosition =
|
|
39
|
-
}.ScheduleParallel(state.Dependency)
|
|
39
|
+
CameraPosition = currentCameraPosition
|
|
40
|
+
}.ScheduleParallel(state.Dependency);
|
|
41
|
+
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
float distanceSq = math.distancesq(_lastCameraPosition, currentCameraPosition);
|
|
46
|
+
|
|
47
|
+
if (distanceSq >= MIN_POSITION_CHANGE_SQ)
|
|
48
|
+
{
|
|
49
|
+
_lastCameraPosition = currentCameraPosition;
|
|
40
50
|
|
|
41
|
-
|
|
51
|
+
state.Dependency = new FollowJob
|
|
42
52
|
{
|
|
43
|
-
|
|
44
|
-
}
|
|
53
|
+
CameraPosition = currentCameraPosition
|
|
54
|
+
}.ScheduleParallel(state.Dependency);
|
|
45
55
|
}
|
|
46
56
|
}
|
|
47
57
|
|
|
@@ -51,6 +61,7 @@ namespace jeanf.scenemanagement
|
|
|
51
61
|
[BurstCompile]
|
|
52
62
|
private partial struct FollowJob : IJobEntity
|
|
53
63
|
{
|
|
64
|
+
[ReadOnly]
|
|
54
65
|
public float3 CameraPosition;
|
|
55
66
|
|
|
56
67
|
public void Execute(ref LocalTransform transform, in FollowComponent _)
|
|
@@ -16,6 +16,10 @@ namespace jeanf.scenemanagement
|
|
|
16
16
|
[Tooltip("Landing zones for manual teleportation between regions")]
|
|
17
17
|
public List<LandingZoneData> landingZones = new List<LandingZoneData>();
|
|
18
18
|
|
|
19
|
+
[Header("Zone Connectivity")]
|
|
20
|
+
[Tooltip("Define which zones are neighbors within the same region")]
|
|
21
|
+
public List<ZoneNeighborData> zoneConnections = new List<ZoneNeighborData>();
|
|
22
|
+
|
|
19
23
|
public List<Zone> GetZonesForRegion(Region region)
|
|
20
24
|
{
|
|
21
25
|
return region != null ? region.zonesInThisRegion : new List<Zone>();
|
|
@@ -32,10 +36,33 @@ namespace jeanf.scenemanagement
|
|
|
32
36
|
return result;
|
|
33
37
|
}
|
|
34
38
|
|
|
39
|
+
public List<Zone> GetNeighborsForZone(Zone zone)
|
|
40
|
+
{
|
|
41
|
+
var result = new List<Zone>();
|
|
42
|
+
foreach (var connection in zoneConnections)
|
|
43
|
+
{
|
|
44
|
+
if (connection.zoneA == zone && connection.zoneB != null)
|
|
45
|
+
result.Add(connection.zoneB);
|
|
46
|
+
else if (connection.zoneB == zone && connection.zoneA != null)
|
|
47
|
+
result.Add(connection.zoneA);
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
|
|
35
52
|
public bool IsRegionActive(Region region)
|
|
36
53
|
{
|
|
37
54
|
return activeRegions.Contains(region);
|
|
38
55
|
}
|
|
56
|
+
|
|
57
|
+
public bool IsLandingZone(Zone zone)
|
|
58
|
+
{
|
|
59
|
+
foreach (var landing in landingZones)
|
|
60
|
+
{
|
|
61
|
+
if (landing.landingZone == zone)
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
39
66
|
}
|
|
40
67
|
|
|
41
68
|
[System.Serializable]
|
|
@@ -44,4 +71,13 @@ namespace jeanf.scenemanagement
|
|
|
44
71
|
public Region region;
|
|
45
72
|
public Zone landingZone;
|
|
46
73
|
}
|
|
74
|
+
|
|
75
|
+
[System.Serializable]
|
|
76
|
+
public class ZoneNeighborData
|
|
77
|
+
{
|
|
78
|
+
public Zone zoneA;
|
|
79
|
+
public Zone zoneB;
|
|
80
|
+
[Tooltip("Bidirectional connection between these zones")]
|
|
81
|
+
public bool isBidirectional = true;
|
|
82
|
+
}
|
|
47
83
|
}
|
|
@@ -16,16 +16,20 @@ namespace jeanf.scenemanagement
|
|
|
16
16
|
private NativeList<Entity> _activeVolumes;
|
|
17
17
|
private NativeList<(Entity, LevelInfo)> _toLoadList;
|
|
18
18
|
private NativeList<(Entity, LevelInfo)> _toUnloadList;
|
|
19
|
-
private NativeHashSet<FixedString128Bytes>
|
|
19
|
+
private NativeHashSet<FixedString128Bytes> _checkableZoneIds;
|
|
20
20
|
|
|
21
21
|
private EntityQuery _relevantQuery;
|
|
22
22
|
private EntityQuery _volumeQuery;
|
|
23
23
|
|
|
24
24
|
private FixedString128Bytes _currentPlayerZone;
|
|
25
|
-
private FixedString128Bytes
|
|
25
|
+
private FixedString128Bytes _currentPlayerRegion;
|
|
26
|
+
private FixedString128Bytes _lastNotifiedZone;
|
|
27
|
+
private FixedString128Bytes _lastNotifiedRegion;
|
|
26
28
|
|
|
27
|
-
private
|
|
28
|
-
private
|
|
29
|
+
private NativeHashMap<FixedString128Bytes, FixedString128Bytes> _zoneToRegionMap;
|
|
30
|
+
private NativeHashMap<FixedString128Bytes, NativeList<FixedString128Bytes>> _zoneNeighbors;
|
|
31
|
+
private NativeHashSet<FixedString128Bytes> _landingZones;
|
|
32
|
+
private bool _mappingInitialized;
|
|
29
33
|
|
|
30
34
|
[BurstCompile]
|
|
31
35
|
public void OnCreate(ref SystemState state)
|
|
@@ -36,8 +40,16 @@ namespace jeanf.scenemanagement
|
|
|
36
40
|
_activeVolumes = new NativeList<Entity>(100, Allocator.Persistent);
|
|
37
41
|
_toLoadList = new NativeList<(Entity, LevelInfo)>(10, Allocator.Persistent);
|
|
38
42
|
_toUnloadList = new NativeList<(Entity, LevelInfo)>(10, Allocator.Persistent);
|
|
39
|
-
|
|
43
|
+
_checkableZoneIds = new NativeHashSet<FixedString128Bytes>(50, Allocator.Persistent);
|
|
44
|
+
_zoneToRegionMap = new NativeHashMap<FixedString128Bytes, FixedString128Bytes>(100, Allocator.Persistent);
|
|
45
|
+
_zoneNeighbors = new NativeHashMap<FixedString128Bytes, NativeList<FixedString128Bytes>>(100, Allocator.Persistent);
|
|
46
|
+
_landingZones = new NativeHashSet<FixedString128Bytes>(50, Allocator.Persistent);
|
|
47
|
+
|
|
40
48
|
_currentPlayerZone = new FixedString128Bytes();
|
|
49
|
+
_currentPlayerRegion = new FixedString128Bytes();
|
|
50
|
+
_lastNotifiedZone = new FixedString128Bytes();
|
|
51
|
+
_lastNotifiedRegion = new FixedString128Bytes();
|
|
52
|
+
_mappingInitialized = false;
|
|
41
53
|
|
|
42
54
|
_relevantQuery = SystemAPI.QueryBuilder().WithAll<Relevant, LocalToWorld>().Build();
|
|
43
55
|
_volumeQuery = SystemAPI.QueryBuilder().WithAll<Volume, LocalToWorld>().Build();
|
|
@@ -49,14 +61,21 @@ namespace jeanf.scenemanagement
|
|
|
49
61
|
if (_activeVolumes.IsCreated) _activeVolumes.Dispose();
|
|
50
62
|
if (_toLoadList.IsCreated) _toLoadList.Dispose();
|
|
51
63
|
if (_toUnloadList.IsCreated) _toUnloadList.Dispose();
|
|
52
|
-
if (
|
|
64
|
+
if (_checkableZoneIds.IsCreated) _checkableZoneIds.Dispose();
|
|
65
|
+
if (_zoneToRegionMap.IsCreated) _zoneToRegionMap.Dispose();
|
|
66
|
+
if (_landingZones.IsCreated) _landingZones.Dispose();
|
|
67
|
+
if (_zoneNeighbors.IsCreated)
|
|
68
|
+
{
|
|
69
|
+
foreach (var kvp in _zoneNeighbors)
|
|
70
|
+
{
|
|
71
|
+
if (kvp.Value.IsCreated) kvp.Value.Dispose();
|
|
72
|
+
}
|
|
73
|
+
_zoneNeighbors.Dispose();
|
|
74
|
+
}
|
|
53
75
|
}
|
|
54
76
|
|
|
55
77
|
public void OnUpdate(ref SystemState state)
|
|
56
78
|
{
|
|
57
|
-
_frameCounter++;
|
|
58
|
-
bool shouldDebug = _frameCounter % DEBUG_FREQUENCY == 0;
|
|
59
|
-
|
|
60
79
|
_activeVolumes.Clear();
|
|
61
80
|
_toLoadList.Clear();
|
|
62
81
|
_toUnloadList.Clear();
|
|
@@ -70,99 +89,178 @@ namespace jeanf.scenemanagement
|
|
|
70
89
|
}
|
|
71
90
|
|
|
72
91
|
var playerPosition = relevantPositions[0].Position;
|
|
92
|
+
relevantPositions.Dispose();
|
|
73
93
|
|
|
74
|
-
|
|
94
|
+
if (!_mappingInitialized)
|
|
95
|
+
{
|
|
96
|
+
BuildConnectivityMappings(ref state);
|
|
97
|
+
_mappingInitialized = true;
|
|
98
|
+
}
|
|
75
99
|
|
|
76
|
-
|
|
77
|
-
var volumeTransforms = _volumeQuery.ToComponentDataArray<LocalToWorld>(Allocator.TempJob);
|
|
78
|
-
var volumes = _volumeQuery.ToComponentDataArray<Volume>(Allocator.TempJob);
|
|
100
|
+
UpdateCheckableZones();
|
|
79
101
|
|
|
80
|
-
|
|
102
|
+
var newPlayerZone = CheckVolumesForPlayerZone(ref state, playerPosition);
|
|
103
|
+
CheckForZoneAndRegionChange(newPlayerZone);
|
|
104
|
+
ProcessLevelLoadingStates(ref state);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private FixedString128Bytes CheckVolumesForPlayerZone(ref SystemState state, float3 playerPosition)
|
|
108
|
+
{
|
|
109
|
+
var newPlayerZone = new FixedString128Bytes();
|
|
81
110
|
|
|
82
|
-
|
|
111
|
+
foreach (var (volume, transform, entity) in
|
|
112
|
+
SystemAPI.Query<RefRO<Volume>, RefRO<LocalToWorld>>().WithEntityAccess())
|
|
83
113
|
{
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (!_relevantZoneIds.Contains(volume.ZoneId) && !volume.ZoneId.IsEmpty)
|
|
114
|
+
if (!ShouldCheckVolume(volume.ValueRO.ZoneId))
|
|
87
115
|
continue;
|
|
88
116
|
|
|
89
|
-
var
|
|
90
|
-
var
|
|
91
|
-
var pos = volumeTransform.Position;
|
|
117
|
+
var range = volume.ValueRO.Scale / 2f;
|
|
118
|
+
var pos = transform.ValueRO.Position;
|
|
92
119
|
var distance = math.abs(playerPosition - pos);
|
|
93
120
|
var insideAxis = (distance < range);
|
|
94
121
|
|
|
95
122
|
if (insideAxis.x && insideAxis.y && insideAxis.z)
|
|
96
123
|
{
|
|
97
|
-
_activeVolumes.Add(
|
|
124
|
+
_activeVolumes.Add(entity);
|
|
98
125
|
|
|
99
|
-
if (!volume.ZoneId.IsEmpty && newPlayerZone.IsEmpty)
|
|
126
|
+
if (!volume.ValueRO.ZoneId.IsEmpty && newPlayerZone.IsEmpty)
|
|
100
127
|
{
|
|
101
|
-
newPlayerZone = volume.ZoneId;
|
|
128
|
+
newPlayerZone = volume.ValueRO.ZoneId;
|
|
102
129
|
}
|
|
103
130
|
}
|
|
104
131
|
}
|
|
105
132
|
|
|
106
|
-
|
|
107
|
-
ProcessLevelLoadingStates(ref state);
|
|
108
|
-
|
|
109
|
-
relevantPositions.Dispose();
|
|
110
|
-
volumeEntities.Dispose();
|
|
111
|
-
volumeTransforms.Dispose();
|
|
112
|
-
volumes.Dispose();
|
|
133
|
+
return newPlayerZone;
|
|
113
134
|
}
|
|
114
135
|
|
|
115
|
-
private void
|
|
136
|
+
private void BuildConnectivityMappings(ref SystemState state)
|
|
116
137
|
{
|
|
117
|
-
|
|
138
|
+
_zoneToRegionMap.Clear();
|
|
139
|
+
_landingZones.Clear();
|
|
140
|
+
|
|
141
|
+
foreach (var kvp in _zoneNeighbors)
|
|
142
|
+
{
|
|
143
|
+
if (kvp.Value.IsCreated) kvp.Value.Dispose();
|
|
144
|
+
}
|
|
145
|
+
_zoneNeighbors.Clear();
|
|
118
146
|
|
|
119
147
|
foreach (var (regionBuffer, zoneBuffer, landingBuffer) in
|
|
120
148
|
SystemAPI.Query<DynamicBuffer<RegionBuffer>, DynamicBuffer<ZoneIdBuffer>, DynamicBuffer<LandingZoneBuffer>>())
|
|
121
149
|
{
|
|
122
|
-
foreach (var
|
|
150
|
+
foreach (var landingData in landingBuffer)
|
|
123
151
|
{
|
|
124
|
-
if (
|
|
152
|
+
if (!landingData.landingZoneId.IsEmpty)
|
|
125
153
|
{
|
|
126
|
-
|
|
127
|
-
{
|
|
128
|
-
var zoneIndex = regionData.zoneStartIndex + i;
|
|
129
|
-
if (zoneIndex < zoneBuffer.Length)
|
|
130
|
-
{
|
|
131
|
-
_relevantZoneIds.Add(zoneBuffer[zoneIndex].zoneId);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
break;
|
|
154
|
+
_landingZones.Add(landingData.landingZoneId);
|
|
135
155
|
}
|
|
136
156
|
}
|
|
137
157
|
|
|
138
|
-
foreach (var
|
|
158
|
+
foreach (var regionData in regionBuffer)
|
|
139
159
|
{
|
|
140
|
-
|
|
160
|
+
var regionZones = new NativeList<FixedString128Bytes>(regionData.zoneCount, Allocator.Temp);
|
|
161
|
+
|
|
162
|
+
for (int i = 0; i < regionData.zoneCount; i++)
|
|
141
163
|
{
|
|
142
|
-
|
|
164
|
+
var zoneIndex = regionData.zoneStartIndex + i;
|
|
165
|
+
if (zoneIndex < zoneBuffer.Length)
|
|
166
|
+
{
|
|
167
|
+
var zoneId = zoneBuffer[zoneIndex].zoneId;
|
|
168
|
+
_zoneToRegionMap.TryAdd(zoneId, regionData.regionId);
|
|
169
|
+
regionZones.Add(zoneId);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
for (int i = 0; i < regionZones.Length; i++)
|
|
174
|
+
{
|
|
175
|
+
var zoneA = regionZones[i];
|
|
176
|
+
if (!_zoneNeighbors.ContainsKey(zoneA))
|
|
177
|
+
{
|
|
178
|
+
_zoneNeighbors[zoneA] = new NativeList<FixedString128Bytes>(10, Allocator.Persistent);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
for (int j = 0; j < regionZones.Length; j++)
|
|
182
|
+
{
|
|
183
|
+
if (i == j) continue;
|
|
184
|
+
var zoneB = regionZones[j];
|
|
185
|
+
_zoneNeighbors[zoneA].Add(zoneB);
|
|
186
|
+
}
|
|
143
187
|
}
|
|
188
|
+
|
|
189
|
+
regionZones.Dispose();
|
|
144
190
|
}
|
|
145
191
|
}
|
|
146
192
|
}
|
|
147
193
|
|
|
148
|
-
private void
|
|
194
|
+
private void UpdateCheckableZones()
|
|
195
|
+
{
|
|
196
|
+
_checkableZoneIds.Clear();
|
|
197
|
+
|
|
198
|
+
if (_currentPlayerZone.IsEmpty)
|
|
199
|
+
{
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
_checkableZoneIds.Add(_currentPlayerZone);
|
|
204
|
+
|
|
205
|
+
if (_zoneNeighbors.TryGetValue(_currentPlayerZone, out var neighbors))
|
|
206
|
+
{
|
|
207
|
+
foreach (var neighbor in neighbors)
|
|
208
|
+
{
|
|
209
|
+
_checkableZoneIds.Add(neighbor);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
foreach (var landingZone in _landingZones)
|
|
214
|
+
{
|
|
215
|
+
_checkableZoneIds.Add(landingZone);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private bool ShouldCheckVolume(FixedString128Bytes zoneId)
|
|
220
|
+
{
|
|
221
|
+
if (zoneId.IsEmpty) return false;
|
|
222
|
+
|
|
223
|
+
if (_currentPlayerZone.IsEmpty)
|
|
224
|
+
{
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return _checkableZoneIds.Contains(zoneId);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
private void CheckForZoneAndRegionChange(FixedString128Bytes newPlayerZone)
|
|
149
232
|
{
|
|
150
|
-
bool
|
|
233
|
+
bool zoneChanged = !_currentPlayerZone.Equals(newPlayerZone);
|
|
234
|
+
bool regionChanged = false;
|
|
235
|
+
FixedString128Bytes newPlayerRegion = new FixedString128Bytes();
|
|
151
236
|
|
|
152
|
-
if (!
|
|
153
|
-
|
|
237
|
+
if (!newPlayerZone.IsEmpty && _zoneToRegionMap.TryGetValue(newPlayerZone, out newPlayerRegion))
|
|
238
|
+
{
|
|
239
|
+
regionChanged = !_currentPlayerRegion.Equals(newPlayerRegion);
|
|
240
|
+
}
|
|
154
241
|
|
|
155
|
-
if (
|
|
156
|
-
|
|
157
|
-
var zoneString = newPlayerZone.ToString();
|
|
158
|
-
|
|
159
|
-
try
|
|
242
|
+
if (zoneChanged)
|
|
160
243
|
{
|
|
244
|
+
_currentPlayerZone = newPlayerZone;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (regionChanged)
|
|
248
|
+
{
|
|
249
|
+
_currentPlayerRegion = newPlayerRegion;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (zoneChanged && !newPlayerZone.IsEmpty && !_lastNotifiedZone.Equals(newPlayerZone))
|
|
253
|
+
{
|
|
254
|
+
_lastNotifiedZone = newPlayerZone;
|
|
255
|
+
var zoneString = newPlayerZone.ToString();
|
|
161
256
|
WorldManager.NotifyZoneChangeFromECS(zoneString);
|
|
162
257
|
}
|
|
163
|
-
|
|
258
|
+
|
|
259
|
+
if (regionChanged && !newPlayerRegion.IsEmpty && !_lastNotifiedRegion.Equals(newPlayerRegion))
|
|
164
260
|
{
|
|
165
|
-
|
|
261
|
+
_lastNotifiedRegion = newPlayerRegion;
|
|
262
|
+
var regionString = newPlayerRegion.ToString();
|
|
263
|
+
WorldManager.NotifyRegionChangeFromECS(regionString);
|
|
166
264
|
}
|
|
167
265
|
}
|
|
168
266
|
|
|
@@ -209,10 +307,5 @@ namespace jeanf.scenemanagement
|
|
|
209
307
|
state.EntityManager.SetComponentData(entity, streamingData);
|
|
210
308
|
}
|
|
211
309
|
}
|
|
212
|
-
|
|
213
|
-
public void SetCurrentRegion(Region region)
|
|
214
|
-
{
|
|
215
|
-
_currentRegionId = region != null ? region.id.ToString() : "";
|
|
216
|
-
}
|
|
217
310
|
}
|
|
218
311
|
}
|
|
@@ -13,12 +13,12 @@ MonoBehaviour:
|
|
|
13
13
|
m_Name: Region_01
|
|
14
14
|
m_EditorClassIdentifier:
|
|
15
15
|
id:
|
|
16
|
-
id:
|
|
16
|
+
id: 05887829-c6fb-4cd5-9a35-ef4ab431c7fe
|
|
17
17
|
Coordinate:
|
|
18
18
|
x: 0
|
|
19
19
|
y: 0
|
|
20
|
-
levelName:
|
|
21
|
-
level:
|
|
20
|
+
levelName: region_01
|
|
21
|
+
level: 1
|
|
22
22
|
scenariosInThisRegion:
|
|
23
23
|
- {fileID: 11400000, guid: da48d91e553f86f47add3deca44799c2, type: 2}
|
|
24
24
|
- {fileID: 11400000, guid: 1085c744a096c374dbfdb13da6e13e6f, type: 2}
|
|
@@ -13,12 +13,12 @@ MonoBehaviour:
|
|
|
13
13
|
m_Name: Region_02
|
|
14
14
|
m_EditorClassIdentifier:
|
|
15
15
|
id:
|
|
16
|
-
id:
|
|
16
|
+
id: 3684dbc5-143b-4b2b-9195-5ab04402213e
|
|
17
17
|
Coordinate:
|
|
18
18
|
x: 0
|
|
19
19
|
y: 0
|
|
20
|
-
levelName:
|
|
21
|
-
level:
|
|
20
|
+
levelName: region_02
|
|
21
|
+
level: 2
|
|
22
22
|
scenariosInThisRegion:
|
|
23
23
|
- {fileID: 11400000, guid: da48d91e553f86f47add3deca44799c2, type: 2}
|
|
24
24
|
- {fileID: 11400000, guid: 1085c744a096c374dbfdb13da6e13e6f, type: 2}
|
|
@@ -709,7 +709,7 @@ PrefabInstance:
|
|
|
709
709
|
- target: {fileID: 8979075195523201058, guid: e87a4cab69290cb40805f373b8ccd8d7,
|
|
710
710
|
type: 3}
|
|
711
711
|
propertyPath: isDebug
|
|
712
|
-
value:
|
|
712
|
+
value: 1
|
|
713
713
|
objectReference: {fileID: 0}
|
|
714
714
|
m_RemovedComponents: []
|
|
715
715
|
m_RemovedGameObjects: []
|
|
@@ -1119,7 +1119,7 @@ Light:
|
|
|
1119
1119
|
m_InnerSpotAngle: 21.80208
|
|
1120
1120
|
m_CookieSize: 10
|
|
1121
1121
|
m_Shadows:
|
|
1122
|
-
m_Type:
|
|
1122
|
+
m_Type: 0
|
|
1123
1123
|
m_Resolution: -1
|
|
1124
1124
|
m_CustomResolution: -1
|
|
1125
1125
|
m_Strength: 1
|
|
@@ -1154,7 +1154,7 @@ Light:
|
|
|
1154
1154
|
m_RenderingLayerMask: 1
|
|
1155
1155
|
m_Lightmapping: 4
|
|
1156
1156
|
m_LightShadowCasterMode: 2
|
|
1157
|
-
m_AreaSize: {x:
|
|
1157
|
+
m_AreaSize: {x: 0.5, y: 0.5}
|
|
1158
1158
|
m_BounceIntensity: 1
|
|
1159
1159
|
m_ColorTemperature: 6570
|
|
1160
1160
|
m_UseColorTemperature: 1
|
|
@@ -1227,7 +1227,7 @@ MonoBehaviour:
|
|
|
1227
1227
|
m_IncludeForPathTracing: 1
|
|
1228
1228
|
m_AreaLightShadowCone: 120
|
|
1229
1229
|
m_UseScreenSpaceShadows: 0
|
|
1230
|
-
m_InteractsWithSky:
|
|
1230
|
+
m_InteractsWithSky: 0
|
|
1231
1231
|
m_AngularDiameter: 0.5
|
|
1232
1232
|
diameterMultiplerMode: 0
|
|
1233
1233
|
diameterMultiplier: 1
|
|
@@ -1314,7 +1314,7 @@ MonoBehaviour:
|
|
|
1314
1314
|
m_ShadowVariant: 0
|
|
1315
1315
|
m_ShadowPrecision: 0
|
|
1316
1316
|
useOldInspector: 0
|
|
1317
|
-
useVolumetric:
|
|
1317
|
+
useVolumetric: 0
|
|
1318
1318
|
featuresFoldout: 1
|
|
1319
1319
|
m_AreaLightEmissiveMeshShadowCastingMode: 0
|
|
1320
1320
|
m_AreaLightEmissiveMeshMotionVectorGenerationMode: 0
|
|
@@ -128,9 +128,13 @@ MonoBehaviour:
|
|
|
128
128
|
isDebug: 0
|
|
129
129
|
ListOfRegions:
|
|
130
130
|
- {fileID: 11400000, guid: bbabf3e47905c1b4da96100c0b4e4484, type: 2}
|
|
131
|
+
- {fileID: 11400000, guid: 3be0bdecc77225043bf1a2f89f5cfc8c, type: 2}
|
|
132
|
+
- {fileID: 11400000, guid: 2b8d92f982a2908409fbc1c952eeebf8, type: 2}
|
|
131
133
|
regionChangeRequestChannel: {fileID: 11400000, guid: 0a0e8a2adda6b6842901101278def4b1,
|
|
132
134
|
type: 2}
|
|
133
135
|
sendTeleportTarget: {fileID: 4547402059037323192}
|
|
136
|
+
_currentPlayerZone: {fileID: 0}
|
|
137
|
+
_currentPlayerRegion: {fileID: 0}
|
|
134
138
|
--- !u!114 &2246953710021239090
|
|
135
139
|
MonoBehaviour:
|
|
136
140
|
m_ObjectHideFlags: 0
|
|
@@ -145,9 +149,11 @@ MonoBehaviour:
|
|
|
145
149
|
m_EditorClassIdentifier:
|
|
146
150
|
BeginScenarioRequest: {fileID: 11400000, guid: 030966fcf034be946ab6123e0405c29b,
|
|
147
151
|
type: 2}
|
|
148
|
-
|
|
152
|
+
EndScenarioRequestSO: {fileID: 11400000, guid: 7c9cef042075e874585508cd8bf5c84e,
|
|
153
|
+
type: 2}
|
|
149
154
|
KillAllScenariosRequest: {fileID: 11400000, guid: 64bcbaf957104ff4fa4e7a96c5c92639,
|
|
150
155
|
type: 2}
|
|
156
|
+
automaticScenarioUnload: 1
|
|
151
157
|
--- !u!1 &2311871612787447076
|
|
152
158
|
GameObject:
|
|
153
159
|
m_ObjectHideFlags: 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fr.jeanf.scenemanagement",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"displayName": "Scene Management",
|
|
5
5
|
"description": "This package contains two scene loading system, one is additive, the other is to load subscenes. \nBoth system are living side-by-side.\nThe dynamic systems handles the loading of all static content (environment) using subscenes.\nThe additive system loads scene additively depending on zone & region and upon scenario load/unload requests. Each region or scenario can have dependency that will remain loaded until either a region or a scenario became irrelevant.",
|
|
6
6
|
"unity": "2021.3",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|