You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
4.2 KiB
C#

3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NUnit.Framework;
using Unity.Netcode;
using UnityEngine.SceneManagement;
namespace Unity.Multiplayer.Samples.Utilities
{
public abstract class TestUtilities
{
const float k_MaxSceneLoadDuration = 10f;
/// <summary>
/// Helper wrapper method for asserting the completion of a network scene load to be used inside Playmode tests.
/// A scene is either loaded successfully, or the loading process has timed out and will throw an exception.
/// </summary>
/// <param name="sceneName"> Name of scene </param>
/// <param name="networkSceneManager"> NetworkSceneManager instance </param>
/// <returns> IEnumerator to track scene load process </returns>
public static IEnumerator AssertIsNetworkSceneLoaded(string sceneName, NetworkSceneManager networkSceneManager)
{
Assert.That(networkSceneManager != null, "NetworkSceneManager instance is null!");
yield return new WaitForNetworkSceneLoad(sceneName, networkSceneManager);
}
/// <summary>
/// Custom IEnumerator class to validate the loading of a Scene by name. If a scene load lasts longer than
/// k_MaxSceneLoadDuration it is considered a timeout.
/// </summary>
public class WaitForSceneLoad : CustomYieldInstruction
{
string m_SceneName;
float m_LoadSceneStart;
float m_MaxLoadDuration;
public override bool keepWaiting
{
get
{
var scene = SceneManager.GetSceneByName(m_SceneName);
var isSceneLoaded = scene.IsValid() && scene.isLoaded;
if (Time.time - m_LoadSceneStart >= m_MaxLoadDuration)
{
throw new Exception($"Timeout for scene load for scene name {m_SceneName}");
}
return !isSceneLoaded;
}
}
public WaitForSceneLoad(string sceneName, float maxLoadDuration = k_MaxSceneLoadDuration)
{
m_LoadSceneStart = Time.time;
m_SceneName = sceneName;
m_MaxLoadDuration = maxLoadDuration;
}
}
/// <summary>
/// Custom IEnumerator class to validate the loading of a Scene through Netcode for GameObjects by name.
/// If a scene load lasts longer than k_MaxSceneLoadDuration it is considered a timeout.
/// </summary>
class WaitForNetworkSceneLoad : CustomYieldInstruction
{
string m_SceneName;
float m_LoadSceneStart;
float m_MaxLoadDuration;
bool m_IsNetworkSceneLoaded;
NetworkSceneManager m_NetworkSceneManager;
public override bool keepWaiting
{
get
{
if (Time.time - m_LoadSceneStart >= m_MaxLoadDuration)
{
m_NetworkSceneManager.OnLoadEventCompleted -= ConfirmSceneLoad;
throw new Exception($"Timeout for network scene load for scene name {m_SceneName}");
}
return !m_IsNetworkSceneLoaded;
}
}
public WaitForNetworkSceneLoad(string sceneName, NetworkSceneManager networkSceneManager, float maxLoadDuration = k_MaxSceneLoadDuration)
{
m_LoadSceneStart = Time.time;
m_SceneName = sceneName;
m_MaxLoadDuration = maxLoadDuration;
m_NetworkSceneManager = networkSceneManager;
m_NetworkSceneManager.OnLoadEventCompleted += ConfirmSceneLoad;
}
void ConfirmSceneLoad(string sceneName, LoadSceneMode loadSceneMode, List<ulong> clientsCompleted, List<ulong> clientsTimedOut)
{
if (sceneName == m_SceneName)
{
m_IsNetworkSceneLoaded = true;
m_NetworkSceneManager.OnLoadEventCompleted -= ConfirmSceneLoad;
}
}
}
}
}