11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4+ using System . Runtime . CompilerServices ;
45using Unity . Collections ;
56using UnityEngine ;
67using 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