Skip to content

Commit 3eb810f

Browse files
authored
fix: remove ownership key not found exception (#1532)
1 parent f3ddcb8 commit 3eb810f

File tree

3 files changed

+35
-16
lines changed

3 files changed

+35
-16
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ Additional documentation and release notes are available at [Multiplayer Documen
2525
- NetworkConfig will no longer throw an OverflowException in GetConfig() when ForceSamePrefabs is enabled and the number of prefabs causes the config blob size to exceed 1300 bytes. (#1385)
2626
- Fixed NetworkVariable not calling NetworkSerialize on INetworkSerializable types (#1383)
2727
- Fixed NullReferenceException on ImportReferences call in NetworkBehaviourILPP (#1434)
28-
2928
- Fixed NetworkObjects not being despawned before they are destroyed during shutdown for client, host, and server instances. (#1390)
29+
- Fixed KeyNotFound exception when removing ownership of a newly spawned NetworkObject that is already owned by the server. (#1500)
3030

3131
### Changed
3232

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -187,28 +187,44 @@ internal void RemoveOwnership(NetworkObject networkObject)
187187
throw new SpawnStateException("Object is not spawned");
188188
}
189189

190-
for (int i = NetworkManager.ConnectedClients[networkObject.OwnerClientId].OwnedObjects.Count - 1;
191-
i > -1;
192-
i--)
190+
// If we made it here then we are the server and if the server is determined to already be the owner
191+
// then ignore the RemoveOwnership invocation.
192+
if (networkObject.OwnerClientId == NetworkManager.ServerClientId)
193193
{
194-
if (NetworkManager.ConnectedClients[networkObject.OwnerClientId].OwnedObjects[i] == networkObject)
194+
return;
195+
}
196+
197+
// Make sure the connected client entry exists before trying to remove ownership.
198+
if (TryGetNetworkClient(networkObject.OwnerClientId, out NetworkClient networkClient))
199+
{
200+
for (int i = networkClient.OwnedObjects.Count - 1; i > -1; i--)
195201
{
196-
NetworkManager.ConnectedClients[networkObject.OwnerClientId].OwnedObjects.RemoveAt(i);
202+
if (networkClient.OwnedObjects[i] == networkObject)
203+
{
204+
networkClient.OwnedObjects.RemoveAt(i);
205+
}
197206
}
198-
}
199207

200-
networkObject.OwnerClientIdInternal = null;
208+
networkObject.OwnerClientIdInternal = null;
201209

202-
var message = new ChangeOwnershipMessage
203-
{
204-
NetworkObjectId = networkObject.NetworkObjectId,
205-
OwnerClientId = networkObject.OwnerClientId
206-
};
207-
var size = NetworkManager.SendMessage(message, NetworkDelivery.ReliableSequenced, NetworkManager.ConnectedClientsIds);
210+
var message = new ChangeOwnershipMessage
211+
{
212+
NetworkObjectId = networkObject.NetworkObjectId,
213+
OwnerClientId = networkObject.OwnerClientId
214+
};
215+
var size = NetworkManager.SendMessage(message, NetworkDelivery.ReliableSequenced, NetworkManager.ConnectedClientsIds);
208216

209-
foreach (var client in NetworkManager.ConnectedClients)
217+
foreach (var client in NetworkManager.ConnectedClients)
218+
{
219+
NetworkManager.NetworkMetrics.TrackOwnershipChangeSent(client.Key, networkObject, size);
220+
}
221+
}
222+
else
210223
{
211-
NetworkManager.NetworkMetrics.TrackOwnershipChangeSent(client.Key, networkObject, size);
224+
if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
225+
{
226+
NetworkLog.LogWarning($"No connected clients prior to removing ownership for {networkObject.name}. Make sure you are not initializing or shutting down when removing ownership.");
227+
}
212228
}
213229
}
214230

com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ public IEnumerator TestOwnershipCallbacks()
115115
Assert.That(clientNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(dummyNetworkObjectId));
116116
}
117117

118+
// Verifies that removing the ownership when the default (server) is already set does not cause
119+
// a Key Not Found Exception
120+
m_ServerNetworkManager.SpawnManager.RemoveOwnership(dummyNetworkObject);
118121

119122
var serverObject = m_ServerNetworkManager.SpawnManager.SpawnedObjects[dummyNetworkObjectId];
120123
var clientObject = m_ClientNetworkManagers[0].SpawnManager.SpawnedObjects[dummyNetworkObjectId];

0 commit comments

Comments
 (0)