using System; using System.Collections.Generic; using System.Text.RegularExpressions; using TMPro; using Unity.Multiplayer.Tools.NetworkSimulator.Runtime; using Unity.Multiplayer.Tools.NetworkSimulator.Runtime.BuiltInScenarios; using Unity.Netcode; using UnityEngine; using UnityEngine.UI; namespace Unity.BossRoom.Utils { public class NetworkSimulatorUIMediator : MonoBehaviour { #if UNITY_EDITOR || DEVELOPMENT_BUILD [SerializeField] NetworkSimulator m_NetworkSimulator; #endif [SerializeField] CanvasGroup m_CanvasGroup; #if UNITY_EDITOR || DEVELOPMENT_BUILD [SerializeField] TMP_Dropdown m_PresetsDropdown; [SerializeField] TMP_Dropdown m_ScenariosDropdown; [SerializeField] Button m_ScenariosButton; [SerializeField] TextMeshProUGUI m_ScenariosButtonText; [SerializeField] TMP_InputField m_LagSpikeDuration; [SerializeField] KeyCode m_OpenWindowKeyCode = KeyCode.Tilde; [SerializeField] List m_ConnectionsCycleConfigurations; [SerializeField] List m_RandomConnectionsSwapConfigurations; [SerializeField] int m_RandomConnectionsSwapChangeIntervalMilliseconds; const int k_NbTouchesToOpenWindow = 5; Dictionary m_SimulatorPresets = new Dictionary(); #endif bool m_Shown; const string k_None = "None"; const string k_ConnectionCyclesScenarioName = "Connections Cycle"; const string k_RandomConnectionSwapScenarioName = "Random Connections Swap"; const string k_PauseString = "Pause"; const string k_ResumeString = "Resume"; void Awake() { #if UNITY_EDITOR || DEVELOPMENT_BUILD InitializeUI(); #endif // Hide UI until ready Hide(); } public void Hide() { m_CanvasGroup.alpha = 0f; m_CanvasGroup.interactable = false; m_CanvasGroup.blocksRaycasts = false; m_Shown = false; } #if UNITY_EDITOR || DEVELOPMENT_BUILD void Start() { NetworkManager.Singleton.OnClientStarted += OnNetworkManagerStarted; NetworkManager.Singleton.OnServerStarted += OnNetworkManagerStarted; } void OnDestroy() { if (NetworkManager.Singleton is not null) { NetworkManager.Singleton.OnClientStarted -= OnNetworkManagerStarted; NetworkManager.Singleton.OnServerStarted -= OnNetworkManagerStarted; } } void OnNetworkManagerStarted() { if (m_NetworkSimulator.IsAvailable) { Show(); } } void OnPresetChanged(int optionIndex) { m_NetworkSimulator.ChangeConnectionPreset(m_SimulatorPresets[m_PresetsDropdown.options[optionIndex].text]); } void OnScenarioChanged(int optionIndex) { var scenarioName = m_ScenariosDropdown.options[optionIndex].text; NetworkScenario scenario = null; switch (scenarioName) { case k_None: m_PresetsDropdown.captionText.color = m_PresetsDropdown.colors.normalColor; m_PresetsDropdown.interactable = true; break; case k_ConnectionCyclesScenarioName: var connectionsCyleScenario = new ConnectionsCycle(); connectionsCyleScenario.Configurations.Clear(); foreach (var configuration in m_ConnectionsCycleConfigurations) { connectionsCyleScenario.Configurations.Add(configuration); } m_PresetsDropdown.captionText.color = m_PresetsDropdown.colors.disabledColor; m_PresetsDropdown.interactable = false; scenario = connectionsCyleScenario; break; case k_RandomConnectionSwapScenarioName: var randomConnectionsSwapScenario = new RandomConnectionsSwap(); randomConnectionsSwapScenario.Configurations.Clear(); foreach (var configuration in m_RandomConnectionsSwapConfigurations) { randomConnectionsSwapScenario.Configurations.Add(configuration); } m_PresetsDropdown.captionText.color = m_PresetsDropdown.colors.disabledColor; m_PresetsDropdown.interactable = false; scenario = randomConnectionsSwapScenario; break; default: Debug.LogError("Invalid Scenario selected."); m_PresetsDropdown.captionText.color = m_PresetsDropdown.colors.normalColor; m_PresetsDropdown.interactable = true; break; } m_NetworkSimulator.Scenario = scenario; if (m_NetworkSimulator.Scenario != null) { m_NetworkSimulator.Scenario.Start(m_NetworkSimulator); } UpdateScenarioButton(); } void Show() { m_CanvasGroup.alpha = 1f; m_CanvasGroup.interactable = true; m_CanvasGroup.blocksRaycasts = true; UpdateScenarioButton(); m_Shown = true; } void ToggleVisibility() { if (m_Shown) { Hide(); } else { Show(); } } void InitializeUI() { // Initialize connection presets dropdown var optionData = new List(); // Adding all available presets foreach (var networkSimulatorPreset in NetworkSimulatorPresets.Values) { m_SimulatorPresets[networkSimulatorPreset.Name] = networkSimulatorPreset; optionData.Add(new TMP_Dropdown.OptionData(networkSimulatorPreset.Name)); } m_PresetsDropdown.AddOptions(optionData); m_PresetsDropdown.onValueChanged.AddListener(OnPresetChanged); // Initialize scenario dropdown optionData = new List(); // Adding empty scenario optionData.Add(new TMP_Dropdown.OptionData(k_None)); // Adding ConnectionsCycle scenario optionData.Add(new TMP_Dropdown.OptionData(k_ConnectionCyclesScenarioName)); // Adding RandomConnectionsSwap scenario optionData.Add(new TMP_Dropdown.OptionData(k_RandomConnectionSwapScenarioName)); m_ScenariosDropdown.AddOptions(optionData); m_ScenariosDropdown.onValueChanged.AddListener(OnScenarioChanged); } void Update() { if (m_NetworkSimulator.IsAvailable) { if (Input.touchCount == k_NbTouchesToOpenWindow && AnyTouchDown() || m_OpenWindowKeyCode != KeyCode.None && Input.GetKeyDown(m_OpenWindowKeyCode)) { ToggleVisibility(); } var selectedPreset = m_PresetsDropdown.options[m_PresetsDropdown.value].text; if (selectedPreset != m_NetworkSimulator.CurrentPreset.Name) { for (var i = 0; i < m_PresetsDropdown.options.Count; i++) { if (m_PresetsDropdown.options[i].text == m_NetworkSimulator.CurrentPreset.Name) { m_PresetsDropdown.value = i; } } } } else { if (m_Shown) { Hide(); } } } static bool AnyTouchDown() { foreach (var touch in Input.touches) { if (touch.phase == TouchPhase.Began) { return true; } } return false; } public void SimulateDisconnect() { m_NetworkSimulator.Disconnect(); } public void TriggerLagSpike() { double.TryParse(m_LagSpikeDuration.text, out var duration); m_NetworkSimulator.TriggerLagSpike(TimeSpan.FromMilliseconds(duration)); } public void SanitizeLagSpikeDurationInputField() { m_LagSpikeDuration.text = Regex.Replace(m_LagSpikeDuration.text, "[^0-9]", ""); } public void TriggerScenario() { if (m_NetworkSimulator.Scenario != null) { m_NetworkSimulator.Scenario.IsPaused = !m_NetworkSimulator.Scenario.IsPaused; UpdateScenarioButton(); } } void UpdateScenarioButton() { if (m_NetworkSimulator.Scenario != null) { m_ScenariosButtonText.text = m_NetworkSimulator.Scenario.IsPaused ? k_ResumeString : k_PauseString; m_ScenariosButton.interactable = true; m_ScenariosButtonText.color = m_ScenariosButton.colors.normalColor; } else { m_ScenariosButtonText.text = "None"; m_ScenariosButton.interactable = false; m_ScenariosButtonText.color = m_ScenariosButton.colors.disabledColor; } } #endif } }