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; /// /// 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. /// /// Name of scene /// NetworkSceneManager instance /// IEnumerator to track scene load process public static IEnumerator AssertIsNetworkSceneLoaded(string sceneName, NetworkSceneManager networkSceneManager) { Assert.That(networkSceneManager != null, "NetworkSceneManager instance is null!"); yield return new WaitForNetworkSceneLoad(sceneName, networkSceneManager); } /// /// 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. /// 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; } } /// /// 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. /// 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 clientsCompleted, List clientsTimedOut) { if (sceneName == m_SceneName) { m_IsNetworkSceneLoaded = true; m_NetworkSceneManager.OnLoadEventCompleted -= ConfirmSceneLoad; } } } } }