using System.Collections;
using NUnit.Framework;
using Unity.Netcode.TestHelpers.Runtime;
using UnityEngine;
using UnityEngine.TestTools;
namespace Unity.Netcode.RuntimeTests
{
///
/// Tests that check OnNetworkDespawn being invoked
///
[TestFixture(HostOrServer.DAHost)]
[TestFixture(HostOrServer.Host)]
[TestFixture(HostOrServer.Server)]
internal class NetworkObjectOnNetworkDespawnTests : NetcodeIntegrationTest
{
private const string k_ObjectName = "TestDespawn";
public enum InstanceTypes
{
Server,
Client
}
protected override int NumberOfClients => 1;
private GameObject m_ObjectToSpawn;
private NetworkObject m_NetworkObject;
private HostOrServer m_HostOrServer;
public NetworkObjectOnNetworkDespawnTests(HostOrServer hostOrServer) : base(hostOrServer)
{
m_HostOrServer = hostOrServer;
}
internal class OnNetworkDespawnTestComponent : NetworkBehaviour
{
public bool OnNetworkDespawnCalled { get; internal set; }
public override void OnNetworkSpawn()
{
OnNetworkDespawnCalled = false;
base.OnNetworkSpawn();
}
public override void OnNetworkDespawn()
{
OnNetworkDespawnCalled = true;
base.OnNetworkDespawn();
}
}
protected override void OnServerAndClientsCreated()
{
m_ObjectToSpawn = CreateNetworkObjectPrefab(k_ObjectName);
m_ObjectToSpawn.AddComponent();
base.OnServerAndClientsCreated();
}
private bool ObjectSpawnedOnAllNetworkManagerInstances()
{
if (!s_GlobalNetworkObjects.ContainsKey(m_ServerNetworkManager.LocalClientId))
{
return false;
}
if (!s_GlobalNetworkObjects[m_ServerNetworkManager.LocalClientId].ContainsKey(m_NetworkObject.NetworkObjectId))
{
return false;
}
foreach (var clientNetworkManager in m_ClientNetworkManagers)
{
if (!s_GlobalNetworkObjects.ContainsKey(clientNetworkManager.LocalClientId))
{
return false;
}
if (!s_GlobalNetworkObjects[clientNetworkManager.LocalClientId].ContainsKey(m_NetworkObject.NetworkObjectId))
{
return false;
}
}
return true;
}
///
/// This test validates that is invoked when the
/// is shutdown.
///
[UnityTest]
public IEnumerator TestNetworkObjectDespawnOnShutdown([Values(InstanceTypes.Server, InstanceTypes.Client)] InstanceTypes despawnCheck)
{
var networkManager = despawnCheck == InstanceTypes.Server ? m_ServerNetworkManager : m_ClientNetworkManagers[0];
var networkManagerOwner = m_ServerNetworkManager;
if (m_DistributedAuthority)
{
networkManagerOwner = networkManager;
}
// Spawn the test object
var spawnedObject = SpawnObject(m_ObjectToSpawn, networkManagerOwner);
m_NetworkObject = spawnedObject.GetComponent();
yield return WaitForConditionOrTimeOut(ObjectSpawnedOnAllNetworkManagerInstances);
AssertOnTimeout($"Timed out waiting for all {nameof(NetworkManager)} instances to spawn {m_NetworkObject.name}!");
// Get the spawned object relative to which NetworkManager instance we are testing.
var relativeSpawnedObject = s_GlobalNetworkObjects[networkManager.LocalClientId][m_NetworkObject.NetworkObjectId];
var onNetworkDespawnTestComponent = relativeSpawnedObject.GetComponent();
// Confirm it is not set before shutting down the NetworkManager
Assert.IsFalse(onNetworkDespawnTestComponent.OnNetworkDespawnCalled, $"{nameof(OnNetworkDespawnTestComponent.OnNetworkDespawnCalled)} was set prior to shutting down!");
// Shutdown the NetworkManager instance we are testing.
networkManager.Shutdown();
// Confirm that OnNetworkDespawn is invoked after shutdown
yield return WaitForConditionOrTimeOut(() => onNetworkDespawnTestComponent.OnNetworkDespawnCalled);
AssertOnTimeout($"Timed out waiting for {nameof(NetworkObject)} instance to despawn on the {despawnCheck} side!");
}
}
}