fix: OnNetworkDespawn is not called on server side when a client disconnects [MTT-5120] (#2323)

* fix
This prevents the issue (when just destroying the GameObject) where any NetworkBehaviour component(s) destroyed before the NetworkObject would not have OnNetworkDespawn invoked.

* test
Adding the test to validate this fix.
This commit is contained in:
Noel Stephens 2022-12-02 12:54:56 -06:00 коммит произвёл GitHub
Родитель 8e348c1e0f
Коммит 101bf34cae
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 47 добавлений и 1 удалений

Просмотреть файл

@ -15,6 +15,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
- The default listen address of `UnityTransport` is now 0.0.0.0. (#2307)
### Fixed
- Fixed server side issue where, depending upon component ordering, some NetworkBehaviour components might not have their OnNetworkDespawn method invoked if the client side disconnected. (#2323)
- Fixed an issue in `UnityTransport` where an exception would be thrown if starting a Relay host/server on WebGL. This exception should only be thrown if using direct connections (where WebGL can't act as a host/server). (#2321)

Просмотреть файл

@ -2082,7 +2082,12 @@ namespace Unity.Netcode
}
else
{
Destroy(playerObject.gameObject);
// Call despawn to assure NetworkBehaviour.OnNetworkDespawn is invoked
// on the server-side (when the client side disconnected).
// This prevents the issue (when just destroying the GameObject) where
// any NetworkBehaviour component(s) destroyed before the NetworkObject
// would not have OnNetworkDespawn invoked.
SpawnManager.DespawnObject(playerObject, true);
}
}
else

Просмотреть файл

@ -241,11 +241,20 @@ namespace Unity.Netcode.TestHelpers.Runtime
{
}
/// <summary>
/// Invoked immediately after the player prefab GameObject is created
/// prior to adding a NetworkObject component
/// </summary>
protected virtual void OnPlayerPrefabGameObjectCreated()
{
}
private void CreatePlayerPrefab()
{
VerboseDebug($"Entering {nameof(CreatePlayerPrefab)}");
// Create playerPrefab
m_PlayerPrefab = new GameObject("Player");
OnPlayerPrefabGameObjectCreated();
NetworkObject networkObject = m_PlayerPrefab.AddComponent<NetworkObject>();
// Make it a prefab

Просмотреть файл

@ -1,5 +1,6 @@
using System.Collections;
using UnityEngine;
using NUnit.Framework;
using UnityEngine.TestTools;
using Unity.Netcode.TestHelpers.Runtime;
using Unity.Netcode.Components;
@ -147,5 +148,35 @@ namespace Unity.Netcode.RuntimeTests
// (validating the fix)
Object.Destroy(parentObject);
}
protected override void OnPlayerPrefabGameObjectCreated()
{
// Adds the SimpleNetworkBehaviour before the NetworkObject
// for OnNetworkDespawnInvokedWhenClientDisconnects testing
m_PlayerPrefab.AddComponent<SimpleNetworkBehaviour>();
}
/// <summary>
/// This validates that upon a client disconnecting, the server-side
/// client's player clone will invoke NetworkBehaviour.OnNetworkDespawn
/// when the component precedes the NetworkObject component.(PR-2323)
/// </summary>
[UnityTest]
public IEnumerator OnNetworkDespawnInvokedWhenClientDisconnects()
{
m_AllowServerToStart = true;
// Now just start the Host
yield return StartServerAndClients();
// Now create and connect a new client
yield return CreateAndStartNewClient();
var serverSidePlayer = m_PlayerNetworkObjects[NetworkManager.ServerClientId][m_ClientNetworkManagers[0].LocalClientId].GetComponent<SimpleNetworkBehaviour>();
yield return StopOneClient(m_ClientNetworkManagers[0]);
Assert.True(serverSidePlayer.OnNetworkDespawnCalled, $"Server-side player clone did not invoke OnNetworkDespawn!");
}
}
}