Skip to content
1 change: 1 addition & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
- The `NetworkManager` functions `GetTransportIdFromClientId` and `GetClientIdFromTransportId` will now return `ulong.MaxValue` when the clientId or transportId do not exist. (#3707)
- Improved performance of the NetworkVariable. (#3683)
- Improved performance around the NetworkBehaviour component. (#3687)
- The first session owner no longer sends two synchronization messages to the service. (#3563)

### Deprecated

Expand Down
18 changes: 15 additions & 3 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,11 @@ internal void SetSessionOwner(ulong sessionOwner)
OnSessionOwnerPromoted?.Invoke(sessionOwner);
}

#if ENABLE_SESSIONOWNER_PROMOTION_NOTIFICATION
public void PromoteSessionOwner(ulong clientId)
#else
internal void PromoteSessionOwner(ulong clientId)
#endif
{
if (!DistributedAuthorityMode)
{
Expand All @@ -258,10 +262,18 @@ internal void PromoteSessionOwner(ulong clientId)
{
SessionOwner = clientId,
};
var clients = ConnectionManager.ConnectedClientIds.Where(c => c != LocalClientId).ToArray();
foreach (var targetClient in clients)

if (CMBServiceConnection)
{
ConnectionManager.SendMessage(ref sessionOwnerMessage, NetworkDelivery.ReliableSequenced, ServerClientId);
}
else
{
ConnectionManager.SendMessage(ref sessionOwnerMessage, NetworkDelivery.ReliableSequenced, targetClient);
var clients = ConnectionManager.ConnectedClientIds.Where(c => c != LocalClientId).ToArray();
foreach (var targetClient in clients)
{
ConnectionManager.SendMessage(ref sessionOwnerMessage, NetworkDelivery.ReliableSequenced, targetClient);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,21 +373,18 @@ public void Handle(ref NetworkContext context)

if (!networkManager.SceneManager.IsRestoringSession)
{
// Synchronize the service with the initial session owner's loaded scenes and spawned objects
networkManager.SceneManager.SynchronizeNetworkObjects(NetworkManager.ServerClientId, true);

// Spawn any in-scene placed NetworkObjects
networkManager.SpawnManager.ServerSpawnSceneObjectsOnStartSweep();

// Synchronize the service with the initial session owner's loaded scenes and spawned objects
networkManager.SceneManager.SynchronizeNetworkObjects(NetworkManager.ServerClientId, true);

// Spawn the local player of the session owner
if (networkManager.AutoSpawnPlayerPrefabClientSide)
{
networkManager.ConnectionManager.CreateAndSpawnPlayer(OwnerClientId);
}

// Synchronize the service with the initial session owner's loaded scenes and spawned objects
networkManager.SceneManager.SynchronizeNetworkObjects(NetworkManager.ServerClientId, true);

// With scene management enabled and since the session owner doesn't send a scene event synchronize to itself,
// we need to notify the session owner that everything should be synchronized/spawned at this time.
networkManager.SpawnManager.NotifyNetworkObjectsSynchronized();
Expand Down