@@ -1978,6 +1978,7 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic
19781978 sceneEventData . ClientSynchronizationMode = ClientSynchronizationMode ;
19791979 sceneEventData . InitializeForSynch ( ) ;
19801980 sceneEventData . TargetClientId = clientId ;
1981+ sceneEventData . SenderClientId = NetworkManager . LocalClientId ;
19811982 sceneEventData . LoadSceneMode = ClientSynchronizationMode ;
19821983 var activeScene = SceneManager . GetActiveScene ( ) ;
19831984 sceneEventData . SceneEventType = SceneEventType . Synchronize ;
@@ -2037,6 +2038,7 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic
20372038 // If we are just a normal client and in distributed authority mode, then always use the known server scene handle
20382039 if ( NetworkManager . DistributedAuthorityMode && NetworkManager . CMBServiceConnection )
20392040 {
2041+ Debug . Log ( $ "[Client-{ NetworkManager . LocalClientId } ] Adding scene to synchronize: { scene . name } ") ;
20402042 sceneEventData . AddSceneToSynchronize ( SceneHashFromNameOrPath ( scene . path ) , ClientSceneHandleToServerSceneHandle [ scene . handle ] ) ;
20412043 }
20422044 else
@@ -2070,13 +2072,16 @@ internal void SynchronizeNetworkObjects(ulong clientId, bool synchronizingServic
20702072
20712073
20722074 // Notify the local server that the client has been sent the synchronize event
2073- OnSceneEvent ? . Invoke ( new SceneEvent ( )
2075+ if ( ! synchronizingService )
20742076 {
2075- SceneEventType = sceneEventData . SceneEventType ,
2076- ClientId = clientId
2077- } ) ;
2077+ OnSceneEvent ? . Invoke ( new SceneEvent ( )
2078+ {
2079+ SceneEventType = SceneEventType . Synchronize ,
2080+ ClientId = clientId
2081+ } ) ;
20782082
2079- OnSynchronize ? . Invoke ( clientId ) ;
2083+ OnSynchronize ? . Invoke ( clientId ) ;
2084+ }
20802085
20812086 EndSceneEvent ( sceneEventData . SceneEventId ) ;
20822087 }
@@ -2100,18 +2105,6 @@ private void OnClientBeginSync(uint sceneEventId)
21002105 sceneEventData . NetworkSceneHandle = sceneHandle ;
21012106 sceneEventData . ClientSceneHash = sceneHash ;
21022107
2103- // If this is the beginning of the synchronization event, then send client a notification that synchronization has begun
2104- if ( sceneHash == sceneEventData . SceneHash )
2105- {
2106- OnSceneEvent ? . Invoke ( new SceneEvent ( )
2107- {
2108- SceneEventType = SceneEventType . Synchronize ,
2109- ClientId = NetworkManager . LocalClientId ,
2110- } ) ;
2111-
2112- OnSynchronize ? . Invoke ( NetworkManager . LocalClientId ) ;
2113- }
2114-
21152108 // Always check to see if the scene needs to be validated
21162109 if ( ! ValidateSceneBeforeLoading ( sceneHash , loadSceneMode ) )
21172110 {
@@ -2311,133 +2304,146 @@ private void HandleClientSceneEvent(uint sceneEventId)
23112304 break ;
23122305 }
23132306 case SceneEventType . Synchronize :
2307+ {
2308+ if ( sceneEventData . IsStartingSynchronization )
23142309 {
2315- if ( ! sceneEventData . IsDoneWithSynchronization ( ) )
2316- {
2317- OnClientBeginSync ( sceneEventId ) ;
2318- }
2319- else
2320- {
2321- // Include anything in the DDOL scene
2322- PopulateScenePlacedObjects ( DontDestroyOnLoadScene , false ) ;
2310+ sceneEventData . IsStartingSynchronization = false ;
23232311
2324- // If needed, set the currently active scene
2325- if ( HashToBuildIndex . ContainsKey ( sceneEventData . ActiveSceneHash ) )
2326- {
2327- var targetActiveScene = SceneManager . GetSceneByBuildIndex ( HashToBuildIndex [ sceneEventData . ActiveSceneHash ] ) ;
2328- if ( targetActiveScene . isLoaded && targetActiveScene . handle != SceneManager . GetActiveScene ( ) . handle )
2329- {
2330- SceneManager . SetActiveScene ( targetActiveScene ) ;
2331- }
2332- }
2333-
2334- // Spawn and Synchronize all NetworkObjects
2335- sceneEventData . SynchronizeSceneNetworkObjects ( NetworkManager ) ;
2312+ OnSceneEvent ? . Invoke ( new SceneEvent ( )
2313+ {
2314+ SceneEventType = SceneEventType . Synchronize ,
2315+ ClientId = NetworkManager . LocalClientId ,
2316+ } ) ;
23362317
2337- // If needed, migrate dynamically spawned NetworkObjects to the same scene as they are on the server
2338- SynchronizeNetworkObjectScene ( ) ;
2318+ OnSynchronize ? . Invoke ( NetworkManager . LocalClientId ) ;
2319+ }
23392320
2340- // Process any pending create object messages that the client received during synchronization
2341- ProcessDeferredCreateObjectMessages ( ) ;
2321+ if ( ! sceneEventData . IsDoneWithSynchronization ( ) )
2322+ {
2323+ OnClientBeginSync ( sceneEventId ) ;
2324+ }
2325+ else
2326+ {
2327+ // Include anything in the DDOL scene
2328+ PopulateScenePlacedObjects ( DontDestroyOnLoadScene , false ) ;
23422329
2343- sceneEventData . SceneEventType = SceneEventType . SynchronizeComplete ;
2344- if ( NetworkManager . DistributedAuthorityMode )
2345- {
2346- sceneEventData . TargetClientId = NetworkManager . CurrentSessionOwner ;
2347- sceneEventData . SenderClientId = NetworkManager . LocalClientId ;
2348- var message = new SceneEventMessage
2349- {
2350- EventData = sceneEventData ,
2351- } ;
2352- var target = NetworkManager . DAHost ? NetworkManager . CurrentSessionOwner : NetworkManager . ServerClientId ;
2353- var size = NetworkManager . ConnectionManager . SendMessage ( ref message , m_NetworkDelivery , target ) ;
2354- NetworkManager . NetworkMetrics . TrackSceneEventSent ( target , ( uint ) sceneEventData . SceneEventType , SceneNameFromHash ( sceneEventData . SceneHash ) , size ) ;
2355- }
2356- else
2330+ // If needed, set the currently active scene
2331+ if ( HashToBuildIndex . ContainsKey ( sceneEventData . ActiveSceneHash ) )
2332+ {
2333+ var targetActiveScene = SceneManager . GetSceneByBuildIndex ( HashToBuildIndex [ sceneEventData . ActiveSceneHash ] ) ;
2334+ if ( targetActiveScene . isLoaded && targetActiveScene . handle != SceneManager . GetActiveScene ( ) . handle )
23572335 {
2358- SendSceneEventData ( sceneEventId , new ulong [ ] { NetworkManager . ServerClientId } ) ;
2336+ SceneManager . SetActiveScene ( targetActiveScene ) ;
23592337 }
2338+ }
23602339
2361- // All scenes are synchronized, let the server know we are done synchronizing
2362- NetworkManager . IsConnectedClient = true ;
2340+ // Spawn and Synchronize all NetworkObjects
2341+ sceneEventData . SynchronizeSceneNetworkObjects ( NetworkManager ) ;
23632342
2364- // With distributed authority, either the client-side automatically spawns the default assigned player prefab or
2365- // if AutoSpawnPlayerPrefabClientSide is disabled the client-side will determine what player prefab to spawn and
2366- // when it gets spawned.
2367- if ( NetworkManager . DistributedAuthorityMode && NetworkManager . AutoSpawnPlayerPrefabClientSide )
2368- {
2369- NetworkManager . ConnectionManager . CreateAndSpawnPlayer ( NetworkManager . LocalClientId ) ;
2370- }
2343+ // If needed, migrate dynamically spawned NetworkObjects to the same scene as they are on the server
2344+ SynchronizeNetworkObjectScene ( ) ;
23712345
2372- // Process any SceneEventType.ObjectSceneChanged messages that
2373- // were deferred while synchronizing and migrate the associated
2374- // NetworkObjects to their newly assigned scenes.
2375- sceneEventData . ProcessDeferredObjectSceneChangedEvents ( ) ;
2346+ // Process any pending create object messages that the client received during synchronization
2347+ ProcessDeferredCreateObjectMessages ( ) ;
23762348
2377- // Only if PostSynchronizationSceneUnloading is set and we are running in client synchronization
2378- // mode additive do we unload any remaining scene that was not synchronized (otherwise any loaded
2379- // scene not synchronized by the server will remain loaded)
2380- if ( PostSynchronizationSceneUnloading && ClientSynchronizationMode == LoadSceneMode . Additive )
2349+ sceneEventData . SceneEventType = SceneEventType . SynchronizeComplete ;
2350+ if ( NetworkManager . DistributedAuthorityMode )
2351+ {
2352+ sceneEventData . TargetClientId = NetworkManager . CurrentSessionOwner ;
2353+ sceneEventData . SenderClientId = NetworkManager . LocalClientId ;
2354+ var message = new SceneEventMessage
23812355 {
2382- SceneManagerHandler . UnloadUnassignedScenes ( NetworkManager ) ;
2383- }
2356+ EventData = sceneEventData ,
2357+ } ;
2358+ var target = NetworkManager . DAHost ? NetworkManager . CurrentSessionOwner : NetworkManager . ServerClientId ;
2359+ var size = NetworkManager . ConnectionManager . SendMessage ( ref message , m_NetworkDelivery , target ) ;
2360+ NetworkManager . NetworkMetrics . TrackSceneEventSent ( target , ( uint ) sceneEventData . SceneEventType , SceneNameFromHash ( sceneEventData . SceneHash ) , size ) ;
2361+ }
2362+ else
2363+ {
2364+ SendSceneEventData ( sceneEventId , new ulong [ ] { NetworkManager . ServerClientId } ) ;
2365+ }
23842366
2385- // Client is now synchronized and fully "connected". This also means the client can send "RPCs" at this time
2386- NetworkManager . ConnectionManager . InvokeOnClientConnectedCallback ( NetworkManager . LocalClientId ) ;
2367+ // All scenes are synchronized, let the server know we are done synchronizing
2368+ NetworkManager . IsConnectedClient = true ;
23872369
2388- // Notify the client that they have finished synchronizing
2389- OnSceneEvent ? . Invoke ( new SceneEvent ( )
2390- {
2391- SceneEventType = sceneEventData . SceneEventType ,
2392- ClientId = NetworkManager . LocalClientId , // Client sent this to the server
2393- } ) ;
2370+ // With distributed authority, either the client-side automatically spawns the default assigned player prefab or
2371+ // if AutoSpawnPlayerPrefabClientSide is disabled the client-side will determine what player prefab to spawn and
2372+ // when it gets spawned.
2373+ if ( NetworkManager . DistributedAuthorityMode && NetworkManager . AutoSpawnPlayerPrefabClientSide )
2374+ {
2375+ NetworkManager . ConnectionManager . CreateAndSpawnPlayer ( NetworkManager . LocalClientId ) ;
2376+ }
23942377
2395- OnSynchronizeComplete ? . Invoke ( NetworkManager . LocalClientId ) ;
2378+ // Process any SceneEventType.ObjectSceneChanged messages that
2379+ // were deferred while synchronizing and migrate the associated
2380+ // NetworkObjects to their newly assigned scenes.
2381+ sceneEventData . ProcessDeferredObjectSceneChangedEvents ( ) ;
23962382
2397- if ( NetworkLog . CurrentLogLevel <= LogLevel . Developer )
2398- {
2399- NetworkLog . LogInfo ( $ "[Client-{ NetworkManager . LocalClientId } ][Scene Management Enabled] Synchronization complete!") ;
2400- }
2401- // For convenience, notify all NetworkBehaviours that synchronization is complete.
2402- NetworkManager . SpawnManager . NotifyNetworkObjectsSynchronized ( ) ;
2383+ // Only if PostSynchronizationSceneUnloading is set and we are running in client synchronization
2384+ // mode additive do we unload any remaining scene that was not synchronized (otherwise any loaded
2385+ // scene not synchronized by the server will remain loaded)
2386+ if ( PostSynchronizationSceneUnloading && ClientSynchronizationMode == LoadSceneMode . Additive )
2387+ {
2388+ SceneManagerHandler . UnloadUnassignedScenes ( NetworkManager ) ;
2389+ }
24032390
2404- if ( NetworkManager . DistributedAuthorityMode && HasSceneAuthority ( ) && IsRestoringSession )
2405- {
2406- IsRestoringSession = false ;
2407- PostSynchronizationSceneUnloading = m_OriginalPostSynchronizationSceneUnloading ;
2408- }
2391+ // Client is now synchronized and fully "connected". This also means the client can send "RPCs" at this time
2392+ NetworkManager . ConnectionManager . InvokeOnClientConnectedCallback ( NetworkManager . LocalClientId ) ;
24092393
2410- EndSceneEvent ( sceneEventId ) ;
2411- }
2412- break ;
2413- }
2414- case SceneEventType . ReSynchronize :
2415- {
2416- // Notify the local client that they have been re-synchronized after being synchronized with an in progress game session
2394+ // Notify the client that they have finished synchronizing
24172395 OnSceneEvent ? . Invoke ( new SceneEvent ( )
24182396 {
24192397 SceneEventType = sceneEventData . SceneEventType ,
2420- ClientId = NetworkManager . ServerClientId , // Server sent this to client
2398+ ClientId = NetworkManager . LocalClientId , // Client sent this to the server
24212399 } ) ;
24222400
2423- EndSceneEvent ( sceneEventId ) ;
2424- break ;
2425- }
2426- case SceneEventType . LoadEventCompleted :
2427- case SceneEventType . UnloadEventCompleted :
2428- {
2429- // Notify the local client that all clients have finished loading or unloading
2430- var clientId = NetworkManager . CMBServiceConnection ? NetworkManager . CurrentSessionOwner : NetworkManager . ServerClientId ;
2431- InvokeSceneEvents ( clientId , sceneEventData ) ;
2401+ OnSynchronizeComplete ? . Invoke ( NetworkManager . LocalClientId ) ;
2402+
2403+ if ( NetworkLog . CurrentLogLevel <= LogLevel . Developer )
2404+ {
2405+ NetworkLog . LogInfo ( $ "[Client-{ NetworkManager . LocalClientId } ][Scene Management Enabled] Synchronization complete!") ;
2406+ }
2407+ // For convenience, notify all NetworkBehaviours that synchronization is complete.
2408+ NetworkManager . SpawnManager . NotifyNetworkObjectsSynchronized ( ) ;
2409+
2410+ if ( NetworkManager . DistributedAuthorityMode && HasSceneAuthority ( ) && IsRestoringSession )
2411+ {
2412+ IsRestoringSession = false ;
2413+ PostSynchronizationSceneUnloading = m_OriginalPostSynchronizationSceneUnloading ;
2414+ }
24322415
24332416 EndSceneEvent ( sceneEventId ) ;
2434- break ;
24352417 }
2436- default :
2418+ break ;
2419+ }
2420+ case SceneEventType . ReSynchronize :
2421+ {
2422+ // Notify the local client that they have been re-synchronized after being synchronized with an in progress game session
2423+ OnSceneEvent ? . Invoke ( new SceneEvent ( )
24372424 {
2438- Debug . LogWarning ( $ "{ sceneEventData . SceneEventType } is not currently supported!") ;
2439- break ;
2440- }
2425+ SceneEventType = sceneEventData . SceneEventType ,
2426+ ClientId = NetworkManager . ServerClientId , // Server sent this to client
2427+ } ) ;
2428+
2429+ EndSceneEvent ( sceneEventId ) ;
2430+ break ;
2431+ }
2432+ case SceneEventType . LoadEventCompleted :
2433+ case SceneEventType . UnloadEventCompleted :
2434+ {
2435+ // Notify the local client that all clients have finished loading or unloading
2436+ var clientId = NetworkManager . CMBServiceConnection ? NetworkManager . CurrentSessionOwner : NetworkManager . ServerClientId ;
2437+ InvokeSceneEvents ( clientId , sceneEventData ) ;
2438+
2439+ EndSceneEvent ( sceneEventId ) ;
2440+ break ;
2441+ }
2442+ default :
2443+ {
2444+ Debug . LogWarning ( $ "{ sceneEventData . SceneEventType } is not currently supported!") ;
2445+ break ;
2446+ }
24412447 }
24422448 }
24432449
0 commit comments