Skip to content

Commit a06aade

Browse files
committed
Fix SceneLoadingAndNotificationsTests
1 parent d97ce93 commit a06aade

File tree

4 files changed

+157
-127
lines changed

4 files changed

+157
-127
lines changed

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

Lines changed: 123 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)