Skip to content

feat: adding NetworkSimulator [MTT-6084] [MTT-6083] #843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
fe85a3c
Upgraded UTP to version 2.0.1
LPLafontaineB May 5, 2023
9037440
changelog
LPLafontaineB May 5, 2023
3c05204
update to utp 2.0.2
LPLafontaineB Jun 1, 2023
48d7ff6
Adding NetworkSimulator
LPLafontaineB May 8, 2023
a8edcab
Adding lag spike and disconnect simulation
LPLafontaineB May 8, 2023
e1e7624
Adding support to trigger scenarios
LPLafontaineB May 16, 2023
7337f72
Adding custom configurations of built-in scenarios
LPLafontaineB May 17, 2023
1720e74
making scenarios start automatically when selected
LPLafontaineB May 18, 2023
d5075f2
setting tab key to open/close netsim window
LPLafontaineB May 18, 2023
3ed542d
removing unneeded method
LPLafontaineB May 18, 2023
8b91d3b
Adding index entry in readme
LPLafontaineB May 19, 2023
43a33ce
changelog entry
LPLafontaineB May 19, 2023
ce6f921
removing unnecessary using directive
LPLafontaineB Jun 2, 2023
dcc10ee
fixing broken link in readme
LPLafontaineB Jun 2, 2023
94c26fd
Updating changelog with instructions on how to bring up in-game NetSi…
LPLafontaineB Jun 2, 2023
8d47ea3
using ifdefs to remove netsim window from non-dev builds
LPLafontaineB Jun 2, 2023
407fad0
made lag spike duration input field easier to see
LPLafontaineB Jun 2, 2023
095c0b0
Update Startup.unity
LPLafontaineB Jun 7, 2023
3c097e5
using NetworkSimulator preset to display the ArtificialLatencyWarning
LPLafontaineB Jun 7, 2023
910e3a1
Moving NetworkSimulatorUIMediator to Utils assembly
LPLafontaineB Jun 7, 2023
e88d3c1
Removing scenarios from in-game UI
LPLafontaineB Jun 7, 2023
2fe4303
updating changelog
LPLafontaineB Jun 7, 2023
68146f5
rearranging buttons
LPLafontaineB Jun 7, 2023
ee99491
Visual updates for the network simulator popup
jilfranco-unity Jun 8, 2023
5b43e43
Fixed a broken reference in the scroll bar, applied some overrides fr…
jilfranco-unity Jun 8, 2023
fe62f57
Adding back scenarios to in-game UI
LPLafontaineB Jun 9, 2023
70effc4
Adding comment
LPLafontaineB Jun 9, 2023
a7ce6a3
formatting
LPLafontaineB Jun 9, 2023
549de82
Merge branch 'develop' into feat/adding-netsim-v2
LPLafontaineB Jun 9, 2023
1013182
moving prebuilt scenarios configurations to serialized fields
LPLafontaineB Jun 9, 2023
9708201
formatting
LPLafontaineB Jun 9, 2023
7121b47
visual updates to the netsim window
jilfranco-unity Jun 9, 2023
8a4cd56
format
LPLafontaineB Jun 9, 2023
4f3f700
removing unneeded casts
LPLafontaineB Jun 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5,326 changes: 5,326 additions & 0 deletions Assets/Prefabs/UI/NetworkSimulator.prefab

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions Assets/Prefabs/UI/NetworkSimulator.prefab.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Assets/Scenes/Startup.unity
Git LFS file not shown
2 changes: 1 addition & 1 deletion Assets/Scripts/Gameplay/UI/IPUIMediator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public static string SanitizePort(string dirtyString)
public static bool AreIpAddressAndPortValid(string ipAddress, string port)
{
var portValid = ushort.TryParse(port, out var portNum);
return portValid && NetworkEndPoint.TryParse(ipAddress, portNum, out var networkEndPoint);
return portValid && NetworkEndpoint.TryParse(ipAddress, portNum, out var networkEndPoint);
}
}
}
3 changes: 2 additions & 1 deletion Assets/Scripts/Gameplay/Unity.BossRoom.Gameplay.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"Unity.BossRoom.ConnectionManagement",
"VContainer",
"Unity.BossRoom.VisualEffects",
"Unity.BossRoom.CameraUtils"
"Unity.BossRoom.CameraUtils",
"Unity.Multiplayer.Tools.NetworkSimulator.Runtime"
],
"includePlatforms": [],
"excludePlatforms": [],
Expand Down
13 changes: 9 additions & 4 deletions Assets/Scripts/Utils/NetworkOverlay/NetworkLatencyWarning.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using TMPro;
using Unity.Multiplayer.Tools.NetworkSimulator.Runtime;
using UnityEngine;
using Unity.Netcode;
using Unity.Netcode.Transports.UTP;
Expand All @@ -10,6 +11,9 @@ namespace Unity.BossRoom.Utils.Editor
{
public class NetworkLatencyWarning : MonoBehaviour
{
[SerializeField]
NetworkSimulator m_NetworkSimulator;

TextMeshProUGUI m_LatencyText;
bool m_LatencyTextCreated;

Expand All @@ -25,10 +29,11 @@ void Update()

// adding this preprocessor directive check since UnityTransport's simulator tools only inject latency in #UNITY_EDITOR or in #DEVELOPMENT_BUILD
#if UNITY_EDITOR || DEVELOPMENT_BUILD
var simulatorParameters = unityTransport.DebugSimulator;
m_ArtificialLatencyEnabled = simulatorParameters.PacketDelayMS > 0 ||
simulatorParameters.PacketJitterMS > 0 ||
simulatorParameters.PacketDropRate > 0;
var currentSimulationPreset = m_NetworkSimulator.CurrentPreset;
m_ArtificialLatencyEnabled = currentSimulationPreset.PacketDelayMs > 0 ||
currentSimulationPreset.PacketJitterMs > 0 ||
currentSimulationPreset.PacketLossInterval > 0 ||
currentSimulationPreset.PacketLossPercent > 0;
#else
m_ArtificialLatencyEnabled = false;
#endif
Expand Down
287 changes: 287 additions & 0 deletions Assets/Scripts/Utils/NetworkSimulatorUIMediator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
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<ConnectionsCycle.Configuration> m_ConnectionsCycleConfigurations;

[SerializeField]
List<RandomConnectionsSwap.Configuration> m_RandomConnectionsSwapConfigurations;

[SerializeField]
int m_RandomConnectionsSwapChangeIntervalMilliseconds;

const int k_NbTouchesToOpenWindow = 5;

Dictionary<string, INetworkSimulatorPreset> m_SimulatorPresets = new Dictionary<string, INetworkSimulatorPreset>();
#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;
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<TMP_Dropdown.OptionData>();
// 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<TMP_Dropdown.OptionData>();

// 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
}
}
3 changes: 3 additions & 0 deletions Assets/Scripts/Utils/NetworkSimulatorUIMediator.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Assets/Scripts/Utils/Unity.BossRoom.Utils.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"references": [
"Unity.TextMeshPro",
"Unity.Netcode.Runtime",
"Unity.Multiplayer.Tools.NetworkSimulator.Runtime",
"Unity.Networking.Transport",
"Unity.Collections"
],
Expand Down
Loading