Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,14 @@ internal NetworkClient AddClient(ulong clientId)
}

var distributedAuthority = NetworkManager.DistributedAuthorityMode;

// If not using DA return early or if using DA and scene management is disabled then exit early Since we use NetworkShow to spawn
// objects on the newly connected client side.
if (!distributedAuthority || distributedAuthority && !NetworkManager.NetworkConfig.EnableSceneManagement)
{
return networkClient;
}

var sessionOwnerId = NetworkManager.CurrentSessionOwner;
var isSessionOwner = NetworkManager.LocalClient.IsSessionOwner;
foreach (var networkObject in NetworkManager.SpawnManager.SpawnedObjectsList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ private void NetworkBehaviourUpdater_Tick()

// Then show any NetworkObjects queued to be made visible/shown
m_NetworkManager.SpawnManager.HandleNetworkObjectShow();

// Handle object redistribution (DA + disabled scene management only)
m_NetworkManager.HandleRedistributionToClients();
}
}
}
38 changes: 24 additions & 14 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,30 @@ public bool DAHost
}
}

// DANGO-TODO-MVP: Remove these properties once the service handles object distribution
internal ulong ClientToRedistribute;
internal bool RedistributeToClient;
internal int TickToRedistribute;
// DANGO-TODO: Determine if this needs to be removed once the service handles object distribution
internal List<ulong> ClientsToRedistribute = new List<ulong>();
internal bool RedistributeToClients;

/// <summary>
/// Handles object redistribution when scene management is disabled.
/// <see cref="NetworkBehaviourUpdater.NetworkBehaviourUpdater_Tick"/>
/// DANGO-TODO: Determine if this needs to be removed once the service handles object distribution
/// </summary>
internal void HandleRedistributionToClients()
{
if (!DistributedAuthorityMode || !RedistributeToClients || NetworkConfig.EnableSceneManagement || ShutdownInProgress)
{
return;
}

foreach (var clientId in ClientsToRedistribute)
{
SpawnManager.DistributeNetworkObjects(clientId);
}
RedistributeToClients = false;
ClientsToRedistribute.Clear();
}


internal List<NetworkObject> DeferredDespawnObjects = new List<NetworkObject>();

Expand Down Expand Up @@ -393,16 +413,6 @@ public void NetworkUpdate(NetworkUpdateStage updateStage)
// This is "ok" to invoke when not processing messages since it is just cleaning up messages that never got handled within their timeout period.
DeferredMessageManager.CleanupStaleTriggers();

// DANGO-TODO-MVP: Remove this once the service handles object distribution
// NOTE: This needs to be the last thing done and should happen exactly at this point
// in the update
if (RedistributeToClient && ServerTime.Tick <= TickToRedistribute)
{
RedistributeToClient = false;
SpawnManager.DistributeNetworkObjects(ClientToRedistribute);
ClientToRedistribute = 0;
}

if (m_ShuttingDown)
{
// Host-server will disconnect any connected clients prior to finalizing its shutdown
Expand Down
10 changes: 5 additions & 5 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2894,7 +2894,7 @@ internal SceneObject GetMessageSceneObject(ulong targetClientId = NetworkManager
SyncObservers = syncObservers,
Observers = syncObservers ? Observers.ToArray() : null,
NetworkSceneHandle = NetworkSceneHandle,
Hash = HostCheckForGlobalObjectIdHashOverride(),
Hash = CheckForGlobalObjectIdHashOverride(),
OwnerObject = this,
TargetClientId = targetClientId
};
Expand Down Expand Up @@ -3246,14 +3246,14 @@ internal void UpdateForSceneChanges()
}

/// <summary>
/// Only applies to Host mode.
/// Only applies to Hosts or session owners (for now)
/// Will return the registered source NetworkPrefab's GlobalObjectIdHash if one exists.
/// Server and Clients will always return the NetworkObject's GlobalObjectIdHash.
/// </summary>
/// <returns></returns>
internal uint HostCheckForGlobalObjectIdHashOverride()
/// <returns>appropriate hash value</returns>
internal uint CheckForGlobalObjectIdHashOverride()
{
if (NetworkManager.IsServer)
if (NetworkManager.IsServer || (NetworkManager.DistributedAuthorityMode && NetworkManager.LocalClient.IsSessionOwner))
{
if (NetworkManager.PrefabHandler.ContainsHandler(this))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,8 @@ private void HandleOwnershipChange(ref NetworkContext context)
// Sanity check that we are not sending duplicated change ownership messages
if (networkObject.OwnerClientId == OwnerClientId)
{
UnityEngine.Debug.LogError($"Unnecessary ownership changed message for {NetworkObjectId}.");
// Ignore the message
// Log error and then ignore the message
UnityEngine.Debug.LogError($"Client-{context.SenderId} ({RequestClientId}) sent unnecessary ownership changed message for {NetworkObjectId}.");
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,24 @@ public void Handle(ref NetworkContext context)
// Don't redistribute for the local instance
if (ClientId != networkManager.LocalClientId)
{
// Synchronize the client with spawned objects (relative to each client)
networkManager.SpawnManager.SynchronizeObjectsToNewlyJoinedClient(ClientId);

// Keeping for reference in case the above doesn't resolve for hidden objects (theoretically it should)
// Show any NetworkObjects that are:
// - Hidden from the session owner
// - Owned by this client
// - Has NetworkObject.SpawnWithObservers set to true (the default)
if (!networkManager.LocalClient.IsSessionOwner)
{
networkManager.SpawnManager.ShowHiddenObjectsToNewlyJoinedClient(ClientId);
}
//if (!networkManager.LocalClient.IsSessionOwner)
//{
// networkManager.SpawnManager.ShowHiddenObjectsToNewlyJoinedClient(ClientId);
//}

// We defer redistribution to the end of the NetworkUpdateStage.PostLateUpdate
networkManager.RedistributeToClient = true;
networkManager.ClientToRedistribute = ClientId;
networkManager.TickToRedistribute = networkManager.ServerTime.Tick + 20;
/// We defer redistribution to happen after NetworkShow has been invoked
/// <see cref="NetworkBehaviourUpdater.NetworkBehaviourUpdater_Tick"/>
/// DANGO-TODO: Determine if this needs to be removed once the service handles object distribution
networkManager.RedistributeToClients = true;
networkManager.ClientsToRedistribute.Add(ClientId);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,6 @@ internal void ChangeOwnership(NetworkObject networkObject, ulong clientId, bool
{
networkObject.ChildNetworkBehaviours[i].UpdateNetworkProperties();
}

size = NetworkManager.ConnectionManager.SendMessage(ref message, NetworkDelivery.ReliableSequenced, NetworkManager.ServerClientId);
NetworkManager.NetworkMetrics.TrackOwnershipChangeSent(NetworkManager.LocalClientId, networkObject, size);
}
Expand Down Expand Up @@ -1982,14 +1981,14 @@ internal void NotifyNetworkObjectsSynchronized()
/// synchronizing in order to "show" (spawn) anything that might be currently hidden from
/// the session owner.
/// </summary>
/// <remarks>
/// Replacement is: SynchronizeObjectsToNewlyJoinedClient
/// </remarks>
internal void ShowHiddenObjectsToNewlyJoinedClient(ulong newClientId)
{
if (!NetworkManager.DistributedAuthorityMode)
if (NetworkManager == null || NetworkManager.ShutdownInProgress && NetworkManager.LogLevel <= LogLevel.Developer)
{
if (NetworkManager == null || !NetworkManager.ShutdownInProgress && NetworkManager.LogLevel <= LogLevel.Developer)
{
Debug.LogWarning($"[Internal Error] {nameof(ShowHiddenObjectsToNewlyJoinedClient)} invoked while !");
}
Debug.LogWarning($"[Internal Error] {nameof(ShowHiddenObjectsToNewlyJoinedClient)} invoked while shutdown is in progress!");
return;
}

Expand Down Expand Up @@ -2025,5 +2024,46 @@ internal void ShowHiddenObjectsToNewlyJoinedClient(ulong newClientId)
}
}
}

internal void SynchronizeObjectsToNewlyJoinedClient(ulong newClientId)
{
if (NetworkManager == null || NetworkManager.ShutdownInProgress && NetworkManager.LogLevel <= LogLevel.Developer)
{
Debug.LogWarning($"[Internal Error] {nameof(SynchronizeObjectsToNewlyJoinedClient)} invoked while shutdown is in progress!");
return;
}

if (!NetworkManager.DistributedAuthorityMode)
{
Debug.LogError($"[Internal Error] {nameof(SynchronizeObjectsToNewlyJoinedClient)} should only be invoked when using a distributed authority network topology!");
return;
}

if (NetworkManager.NetworkConfig.EnableSceneManagement)
{
Debug.LogError($"[Internal Error] {nameof(SynchronizeObjectsToNewlyJoinedClient)} should only be invoked when scene management is disabled!");
return;
}

var localClientId = NetworkManager.LocalClient.ClientId;
foreach (var networkObject in SpawnedObjectsList)
{
if (networkObject.SpawnWithObservers && networkObject.OwnerClientId == localClientId)
{
if (networkObject.Observers.Contains(newClientId))
{
if (NetworkManager.LogLevel <= LogLevel.Developer)
{
// Temporary tracking to make sure we are not showing something already visibile (should never be the case for this)
Debug.LogWarning($"[{nameof(SynchronizeObjectsToNewlyJoinedClient)}][{networkObject.name}] New client as already an observer!");
}
// For now, remove the client (impossible for the new client to have an instance since the session owner doesn't) to make sure newly added
// code to handle this edge case works.
networkObject.Observers.Remove(newClientId);
}
networkObject.NetworkShow(newClientId);
}
}
}
}
}
Loading