diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs index 77d32fa0fd..f1b184444c 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs @@ -1291,21 +1291,12 @@ public void DisconnectClient(ulong clientId) throw new NotServerException("Only server can disconnect remote clients. Use StopClient instead."); } - ConnectedClients.Remove(clientId); - PendingClients.Remove(clientId); - - for (int i = ConnectedClientsList.Count - 1; i > -1; i--) - { - if (ConnectedClientsList[i].ClientId == clientId) - { - ConnectedClientsList.RemoveAt(i); - } - } + OnClientDisconnectFromServer(clientId); NetworkConfig.NetworkTransport.DisconnectRemoteClient(clientId); } - internal void OnClientDisconnectFromServer(ulong clientId) + private void OnClientDisconnectFromServer(ulong clientId) { PendingClients.Remove(clientId); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DisconnectTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DisconnectTests.cs new file mode 100644 index 0000000000..45fb045a08 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DisconnectTests.cs @@ -0,0 +1,53 @@ +using System.Collections; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace Unity.Netcode.RuntimeTests +{ + public class DisconnectTests + { + [UnityTest] + public IEnumerator RemoteDisconnectPlayerObjectCleanup() + { + // create server and client instances + MultiInstanceHelpers.Create(1, out NetworkManager server, out NetworkManager[] clients); + + // create prefab + var gameObject = new GameObject("PlayerObject"); + var networkObject = gameObject.AddComponent(); + networkObject.DontDestroyWithOwner = true; + MultiInstanceHelpers.MakeNetworkObjectTestPrefab(networkObject); + + server.NetworkConfig.PlayerPrefab = gameObject; + + for (int i = 0; i < clients.Length; i++) + { + clients[i].NetworkConfig.PlayerPrefab = gameObject; + } + + // start server and connect clients + MultiInstanceHelpers.Start(false, server, clients); + + // wait for connection on client side + yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.WaitForClientsConnected(clients)); + + // wait for connection on server side + yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.WaitForClientConnectedToServer(server)); + + // disconnect the remote client + server.DisconnectClient(clients[0].LocalClientId); + + // wait 1 frame because destroys are delayed + var nextFrameNumber = Time.frameCount + 1; + yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber); + + // ensure the object was destroyed + Assert.False(server.SpawnManager.SpawnedObjects.Any(x => x.Value.IsPlayerObject && x.Value.OwnerClientId == clients[0].LocalClientId)); + + // cleanup + MultiInstanceHelpers.Destroy(); + } + } +} diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DisconnectTests.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/DisconnectTests.cs.meta new file mode 100644 index 0000000000..5528fb9435 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DisconnectTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b05b4daca3854ff6b01a1f002d433dd6 +timeCreated: 1631652586 \ No newline at end of file