Skip to content

Commit 59f420b

Browse files
committed
fix: [Backport] MTTB-1273 Inconsistent scene name in scene event
1 parent 7ed7a52 commit 59f420b

File tree

4 files changed

+388
-157
lines changed

4 files changed

+388
-157
lines changed

com.unity.netcode.gameobjects/Runtime/SceneManagement/NetworkSceneManager.cs

Lines changed: 76 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Runtime.CompilerServices;
45
using Unity.Collections;
56
using UnityEngine;
67
using UnityEngine.SceneManagement;
@@ -62,6 +63,20 @@ public class SceneEvent
6263
/// </summary>
6364
public string SceneName;
6465

66+
/// <summary>
67+
/// This will be set to the path to the scene that the event pertains to.<br />
68+
/// This is set for the following <see cref="Netcode.SceneEventType"/>s:
69+
/// <list type="bullet">
70+
/// <item><term><see cref="SceneEventType.Load"/></term></item>
71+
/// <item><term><see cref="SceneEventType.Unload"/></term></item>
72+
/// <item><term><see cref="SceneEventType.LoadComplete"/></term></item>
73+
/// <item><term><see cref="SceneEventType.UnloadComplete"/></term></item>
74+
/// <item><term><see cref="SceneEventType.LoadEventCompleted"/></term></item>
75+
/// <item><term><see cref="SceneEventType.UnloadEventCompleted"/></term></item>
76+
/// </list>
77+
/// </summary>
78+
public string ScenePath;
79+
6580
/// <summary>
6681
/// When a scene is loaded, the Scene structure is returned.<br />
6782
/// This is set for the following <see cref="Netcode.SceneEventType"/>s:
@@ -1125,24 +1140,7 @@ private bool OnSceneEventProgressCompleted(SceneEventProgress sceneEventProgress
11251140
size);
11261141

11271142
// Send a local notification to the server that all clients are done loading or unloading
1128-
OnSceneEvent?.Invoke(new SceneEvent()
1129-
{
1130-
SceneEventType = sceneEventProgress.SceneEventType,
1131-
SceneName = SceneNameFromHash(sceneEventProgress.SceneHash),
1132-
ClientId = NetworkManager.ServerClientId,
1133-
LoadSceneMode = sceneEventProgress.LoadSceneMode,
1134-
ClientsThatCompleted = clientsThatCompleted,
1135-
ClientsThatTimedOut = clientsThatTimedOut,
1136-
});
1137-
1138-
if (sceneEventData.SceneEventType == SceneEventType.LoadEventCompleted)
1139-
{
1140-
OnLoadEventCompleted?.Invoke(SceneNameFromHash(sceneEventProgress.SceneHash), sceneEventProgress.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
1141-
}
1142-
else
1143-
{
1144-
OnUnloadEventCompleted?.Invoke(SceneNameFromHash(sceneEventProgress.SceneHash), sceneEventProgress.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
1145-
}
1143+
InvokeSceneEvents(NetworkManager.ServerClientId, sceneEventData);
11461144

11471145
EndSceneEvent(sceneEventData.SceneEventId);
11481146
return true;
@@ -1177,6 +1175,7 @@ public SceneEventProgressStatus UnloadScene(Scene scene)
11771175
Debug.LogError($"{nameof(UnloadScene)} internal error! {sceneName} with handle {scene.handle} is not within the internal scenes loaded dictionary!");
11781176
return SceneEventProgressStatus.InternalNetcodeError;
11791177
}
1178+
sceneEventProgress.LoadSceneMode = LoadSceneMode.Additive;
11801179

11811180
// Any NetworkObjects marked to not be destroyed with a scene and reside within the scene about to be unloaded
11821181
// should be migrated temporarily into the DDOL, once the scene is unloaded they will be migrated into the
@@ -1199,16 +1198,7 @@ public SceneEventProgressStatus UnloadScene(Scene scene)
11991198
sceneEventProgress.OnSceneEventCompleted = OnSceneUnloaded;
12001199
var sceneUnload = SceneManagerHandler.UnloadSceneAsync(scene, sceneEventProgress);
12011200
// Notify local server that a scene is going to be unloaded
1202-
OnSceneEvent?.Invoke(new SceneEvent()
1203-
{
1204-
AsyncOperation = sceneUnload,
1205-
SceneEventType = sceneEventData.SceneEventType,
1206-
LoadSceneMode = sceneEventData.LoadSceneMode,
1207-
SceneName = sceneName,
1208-
ClientId = NetworkManager.ServerClientId // Server can only invoke this
1209-
});
1210-
1211-
OnUnload?.Invoke(NetworkManager.ServerClientId, sceneName, sceneUnload);
1201+
InvokeSceneEvents(NetworkManager.ServerClientId, sceneEventData);
12121202

12131203
//Return the status
12141204
return sceneEventProgress.Status;
@@ -1265,16 +1255,7 @@ private void OnClientUnloadScene(uint sceneEventId)
12651255
}
12661256

12671257
// Notify the local client that a scene is going to be unloaded
1268-
OnSceneEvent?.Invoke(new SceneEvent()
1269-
{
1270-
AsyncOperation = sceneUnload,
1271-
SceneEventType = sceneEventData.SceneEventType,
1272-
LoadSceneMode = LoadSceneMode.Additive, // The only scenes unloaded are scenes that were additively loaded
1273-
SceneName = sceneName,
1274-
ClientId = NetworkManager.LocalClientId // Server sent this message to the client, but client is executing it
1275-
});
1276-
1277-
OnUnload?.Invoke(NetworkManager.LocalClientId, sceneName, sceneUnload);
1258+
InvokeSceneEvents(NetworkManager.LocalClientId, sceneEventData);
12781259
}
12791260

12801261
/// <summary>
@@ -1312,15 +1293,8 @@ private void OnSceneUnloaded(uint sceneEventId)
13121293
sceneEventData.SceneEventType = SceneEventType.UnloadComplete;
13131294

13141295
//Notify the client or server that a scene was unloaded
1315-
OnSceneEvent?.Invoke(new SceneEvent()
1316-
{
1317-
SceneEventType = sceneEventData.SceneEventType,
1318-
LoadSceneMode = sceneEventData.LoadSceneMode,
1319-
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
1320-
ClientId = NetworkManager.IsServer ? NetworkManager.ServerClientId : NetworkManager.LocalClientId
1321-
});
1322-
1323-
OnUnloadComplete?.Invoke(NetworkManager.LocalClientId, SceneNameFromHash(sceneEventData.SceneHash));
1296+
var client = NetworkManager.IsServer ? NetworkManager.ServerClientId : NetworkManager.LocalClientId;
1297+
InvokeSceneEvents(client, sceneEventData);
13241298

13251299
// Clients send a notification back to the server they have completed the unload scene event
13261300
if (!NetworkManager.IsServer)
@@ -1395,6 +1369,8 @@ public SceneEventProgressStatus LoadScene(string sceneName, LoadSceneMode loadSc
13951369
sceneEventData.SceneHash = SceneHashFromNameOrPath(sceneName);
13961370
sceneEventData.LoadSceneMode = loadSceneMode;
13971371
var sceneEventId = sceneEventData.SceneEventId;
1372+
// LoadScene can be called with either a sceneName or a scenePath. Ensure that sceneName is correct at this point
1373+
sceneName = SceneNameFromHash(sceneEventData.SceneHash);
13981374
// This both checks to make sure the scene is valid and if not resets the active scene event
13991375
m_IsSceneEventActive = ValidateSceneBeforeLoading(sceneEventData.SceneHash, loadSceneMode);
14001376
if (!m_IsSceneEventActive)
@@ -1430,16 +1406,7 @@ public SceneEventProgressStatus LoadScene(string sceneName, LoadSceneMode loadSc
14301406
sceneEventProgress.OnSceneEventCompleted = OnSceneLoaded;
14311407
var sceneLoad = SceneManagerHandler.LoadSceneAsync(sceneName, loadSceneMode, sceneEventProgress);
14321408
// Notify the local server that a scene loading event has begun
1433-
OnSceneEvent?.Invoke(new SceneEvent()
1434-
{
1435-
AsyncOperation = sceneLoad,
1436-
SceneEventType = sceneEventData.SceneEventType,
1437-
LoadSceneMode = sceneEventData.LoadSceneMode,
1438-
SceneName = sceneName,
1439-
ClientId = NetworkManager.ServerClientId
1440-
});
1441-
1442-
OnLoad?.Invoke(NetworkManager.ServerClientId, sceneName, sceneEventData.LoadSceneMode, sceneLoad);
1409+
InvokeSceneEvents(NetworkManager.ServerClientId, sceneEventData, sceneLoad);
14431410

14441411
//Return our scene progress instance
14451412
return sceneEventProgress.Status;
@@ -1521,6 +1488,7 @@ private void SceneUnloaded(Scene scene)
15211488
AsyncOperation = m_AsyncOperation,
15221489
SceneEventType = SceneEventType.UnloadComplete,
15231490
SceneName = m_Scene.name,
1491+
ScenePath = m_Scene.path,
15241492
LoadSceneMode = m_LoadSceneMode,
15251493
ClientId = m_ClientId
15261494
});
@@ -1545,6 +1513,7 @@ private SceneUnloadEventHandler(NetworkSceneManager networkSceneManager, Scene s
15451513
AsyncOperation = m_AsyncOperation,
15461514
SceneEventType = SceneEventType.Unload,
15471515
SceneName = m_Scene.name,
1516+
ScenePath = m_Scene.path,
15481517
LoadSceneMode = m_LoadSceneMode,
15491518
ClientId = clientId
15501519
});
@@ -1599,16 +1568,7 @@ private void OnClientSceneLoadingEvent(uint sceneEventId)
15991568
};
16001569
var sceneLoad = SceneManagerHandler.LoadSceneAsync(sceneName, sceneEventData.LoadSceneMode, sceneEventProgress);
16011570

1602-
OnSceneEvent?.Invoke(new SceneEvent()
1603-
{
1604-
AsyncOperation = sceneLoad,
1605-
SceneEventType = sceneEventData.SceneEventType,
1606-
LoadSceneMode = sceneEventData.LoadSceneMode,
1607-
SceneName = sceneName,
1608-
ClientId = NetworkManager.LocalClientId
1609-
});
1610-
1611-
OnLoad?.Invoke(NetworkManager.LocalClientId, sceneName, sceneEventData.LoadSceneMode, sceneLoad);
1571+
InvokeSceneEvents(NetworkManager.LocalClientId, sceneEventData, sceneLoad);
16121572
}
16131573

16141574
/// <summary>
@@ -1723,17 +1683,9 @@ private void OnServerLoadedScene(uint sceneEventId, Scene scene)
17231683
}
17241684

17251685
m_IsSceneEventActive = false;
1686+
sceneEventData.SceneEventType = SceneEventType.LoadComplete;
17261687
//First, notify local server that the scene was loaded
1727-
OnSceneEvent?.Invoke(new SceneEvent()
1728-
{
1729-
SceneEventType = SceneEventType.LoadComplete,
1730-
LoadSceneMode = sceneEventData.LoadSceneMode,
1731-
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
1732-
ClientId = NetworkManager.ServerClientId,
1733-
Scene = scene,
1734-
});
1735-
1736-
OnLoadComplete?.Invoke(NetworkManager.ServerClientId, SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode);
1688+
InvokeSceneEvents(NetworkManager.ServerClientId, sceneEventData, scene: scene);
17371689

17381690
//Second, only if we are a host do we want register having loaded for the associated SceneEventProgress
17391691
if (SceneEventProgressTracking.ContainsKey(sceneEventData.SceneEventProgressId) && NetworkManager.IsHost)
@@ -1760,16 +1712,7 @@ private void OnClientLoadedScene(uint sceneEventId, Scene scene)
17601712
ProcessDeferredCreateObjectMessages();
17611713

17621714
// Notify local client that the scene was loaded
1763-
OnSceneEvent?.Invoke(new SceneEvent()
1764-
{
1765-
SceneEventType = SceneEventType.LoadComplete,
1766-
LoadSceneMode = sceneEventData.LoadSceneMode,
1767-
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
1768-
ClientId = NetworkManager.LocalClientId,
1769-
Scene = scene,
1770-
});
1771-
1772-
OnLoadComplete?.Invoke(NetworkManager.LocalClientId, SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode);
1715+
InvokeSceneEvents(NetworkManager.LocalClientId, sceneEventData, scene: scene);
17731716

17741717
EndSceneEvent(sceneEventId);
17751718
}
@@ -1925,16 +1868,7 @@ private void OnClientBeginSync(uint sceneEventId)
19251868
sceneLoad = SceneManagerHandler.LoadSceneAsync(sceneName, loadSceneMode, sceneEventProgress);
19261869

19271870
// Notify local client that a scene load has begun
1928-
OnSceneEvent?.Invoke(new SceneEvent()
1929-
{
1930-
AsyncOperation = sceneLoad,
1931-
SceneEventType = SceneEventType.Load,
1932-
LoadSceneMode = loadSceneMode,
1933-
SceneName = sceneName,
1934-
ClientId = NetworkManager.LocalClientId,
1935-
});
1936-
1937-
OnLoad?.Invoke(NetworkManager.LocalClientId, sceneName, loadSceneMode, sceneLoad);
1871+
InvokeSceneEvents(NetworkManager.LocalClientId, sceneEventData, sceneLoad);
19381872
}
19391873
else
19401874
{
@@ -1999,16 +1933,7 @@ private void ClientLoadedSynchronization(uint sceneEventId)
19991933
EndSceneEvent(responseSceneEventData.SceneEventId);
20001934

20011935
// Send notification to local client that the scene has finished loading
2002-
OnSceneEvent?.Invoke(new SceneEvent()
2003-
{
2004-
SceneEventType = SceneEventType.LoadComplete,
2005-
LoadSceneMode = loadSceneMode,
2006-
SceneName = sceneName,
2007-
Scene = nextScene,
2008-
ClientId = NetworkManager.LocalClientId,
2009-
});
2010-
2011-
OnLoadComplete?.Invoke(NetworkManager.LocalClientId, sceneName, loadSceneMode);
1936+
InvokeSceneEvents(NetworkManager.LocalClientId, responseSceneEventData);
20121937

20131938
// Check to see if we still have scenes to load and synchronize with
20141939
HandleClientSceneEvent(sceneEventId);
@@ -2180,27 +2105,8 @@ private void HandleClientSceneEvent(uint sceneEventId)
21802105
case SceneEventType.UnloadEventCompleted:
21812106
{
21822107
// Notify the local client that all clients have finished loading or unloading
2183-
OnSceneEvent?.Invoke(new SceneEvent()
2184-
{
2185-
SceneEventType = sceneEventData.SceneEventType,
2186-
LoadSceneMode = sceneEventData.LoadSceneMode,
2187-
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
2188-
ClientId = NetworkManager.ServerClientId,
2189-
ClientsThatCompleted = sceneEventData.ClientsCompleted,
2190-
ClientsThatTimedOut = sceneEventData.ClientsTimedOut,
2191-
});
2192-
2193-
if (sceneEventData.SceneEventType == SceneEventType.LoadEventCompleted)
2194-
{
2195-
OnLoadEventCompleted?.Invoke(SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
2196-
}
2197-
else
2198-
{
2199-
OnUnloadEventCompleted?.Invoke(SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode, sceneEventData.ClientsCompleted, sceneEventData.ClientsTimedOut);
2200-
}
2201-
2108+
InvokeSceneEvents(NetworkManager.ServerClientId, sceneEventData);
22022109
EndSceneEvent(sceneEventId);
2203-
22042110
break;
22052111
}
22062112
default:
@@ -2221,41 +2127,15 @@ private void HandleServerSceneEvent(uint sceneEventId, ulong clientId)
22212127
switch (sceneEventData.SceneEventType)
22222128
{
22232129
case SceneEventType.LoadComplete:
2224-
{
2225-
// Notify the local server that the client has finished loading a scene
2226-
OnSceneEvent?.Invoke(new SceneEvent()
2227-
{
2228-
SceneEventType = sceneEventData.SceneEventType,
2229-
LoadSceneMode = sceneEventData.LoadSceneMode,
2230-
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
2231-
ClientId = clientId
2232-
});
2233-
2234-
OnLoadComplete?.Invoke(clientId, SceneNameFromHash(sceneEventData.SceneHash), sceneEventData.LoadSceneMode);
2235-
2236-
if (SceneEventProgressTracking.ContainsKey(sceneEventData.SceneEventProgressId))
2237-
{
2238-
SceneEventProgressTracking[sceneEventData.SceneEventProgressId].ClientFinishedSceneEvent(clientId);
2239-
}
2240-
EndSceneEvent(sceneEventId);
2241-
break;
2242-
}
22432130
case SceneEventType.UnloadComplete:
22442131
{
2132+
// Notify the local server that the client has finished unloading a scene
2133+
InvokeSceneEvents(clientId, sceneEventData);
2134+
22452135
if (SceneEventProgressTracking.ContainsKey(sceneEventData.SceneEventProgressId))
22462136
{
22472137
SceneEventProgressTracking[sceneEventData.SceneEventProgressId].ClientFinishedSceneEvent(clientId);
22482138
}
2249-
// Notify the local server that the client has finished unloading a scene
2250-
OnSceneEvent?.Invoke(new SceneEvent()
2251-
{
2252-
SceneEventType = sceneEventData.SceneEventType,
2253-
LoadSceneMode = sceneEventData.LoadSceneMode,
2254-
SceneName = SceneNameFromHash(sceneEventData.SceneHash),
2255-
ClientId = clientId
2256-
});
2257-
2258-
OnUnloadComplete?.Invoke(clientId, SceneNameFromHash(sceneEventData.SceneHash));
22592139

22602140
EndSceneEvent(sceneEventId);
22612141
break;
@@ -2670,5 +2550,45 @@ private void ProcessDeferredCreateObjectMessages()
26702550
DeferredObjectCreationCount = DeferredObjectCreationList.Count;
26712551
DeferredObjectCreationList.Clear();
26722552
}
2553+
2554+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2555+
private void InvokeSceneEvents(ulong clientId, SceneEventData eventData, AsyncOperation asyncOperation = null, Scene scene = default)
2556+
{
2557+
var sceneName = SceneNameFromHash(eventData.SceneHash);
2558+
OnSceneEvent?.Invoke(new SceneEvent()
2559+
{
2560+
AsyncOperation = asyncOperation,
2561+
SceneEventType = eventData.SceneEventType,
2562+
SceneName = sceneName,
2563+
ScenePath = ScenePathFromHash(eventData.SceneHash),
2564+
ClientId = clientId,
2565+
LoadSceneMode = eventData.LoadSceneMode,
2566+
ClientsThatCompleted = eventData.ClientsCompleted,
2567+
ClientsThatTimedOut = eventData.ClientsTimedOut,
2568+
Scene = scene,
2569+
});
2570+
2571+
switch (eventData.SceneEventType)
2572+
{
2573+
case SceneEventType.Load:
2574+
OnLoad?.Invoke(clientId, sceneName, eventData.LoadSceneMode, asyncOperation);
2575+
break;
2576+
case SceneEventType.Unload:
2577+
OnUnload?.Invoke(clientId, sceneName, asyncOperation);
2578+
break;
2579+
case SceneEventType.LoadComplete:
2580+
OnLoadComplete?.Invoke(clientId, sceneName, eventData.LoadSceneMode);
2581+
break;
2582+
case SceneEventType.UnloadComplete:
2583+
OnUnloadComplete?.Invoke(clientId, sceneName);
2584+
break;
2585+
case SceneEventType.LoadEventCompleted:
2586+
OnLoadEventCompleted?.Invoke(SceneNameFromHash(eventData.SceneHash), eventData.LoadSceneMode, eventData.ClientsCompleted, eventData.ClientsTimedOut);
2587+
break;
2588+
case SceneEventType.UnloadEventCompleted:
2589+
OnUnloadEventCompleted?.Invoke(SceneNameFromHash(eventData.SceneHash), eventData.LoadSceneMode, eventData.ClientsCompleted, eventData.ClientsTimedOut);
2590+
break;
2591+
}
2592+
}
26732593
}
26742594
}

0 commit comments

Comments
 (0)