Skip to content

Commit e05bfdf

Browse files
feat: bad network conditions warning [MTT-3242] (#632)
* Adding text warning to UI when UTP RTT is over a threshold * Added coloring of stats text (becomes yellow after 130ms UTP RTT and red after 200ms) * Using TMP for NetworkLatencyWarning and increasing font size * extracted duplicated methods to NetworkOverlay * increased width of Vetical Layout Group in Debug Overlay Canvas Co-authored-by: Sam Bellomo <[email protected]>
1 parent edd5b64 commit e05bfdf

File tree

5 files changed

+56
-34
lines changed

5 files changed

+56
-34
lines changed

Assets/BossRoom/Prefabs/Debug Overlay Canvas.prefab

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ RectTransform:
2929
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
3030
m_LocalPosition: {x: 0, y: 0, z: 0}
3131
m_LocalScale: {x: 0, y: 0, z: 0}
32+
m_ConstrainProportionsScale: 0
3233
m_Children:
3334
- {fileID: 2084502874807427418}
3435
m_Father: {fileID: 0}
@@ -72,10 +73,10 @@ MonoBehaviour:
7273
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
7374
m_Name:
7475
m_EditorClassIdentifier:
75-
m_UiScaleMode: 0
76+
m_UiScaleMode: 1
7677
m_ReferencePixelsPerUnit: 100
7778
m_ScaleFactor: 1
78-
m_ReferenceResolution: {x: 800, y: 600}
79+
m_ReferenceResolution: {x: 1920, y: 1080}
7980
m_ScreenMatchMode: 0
8081
m_MatchWidthOrHeight: 0
8182
m_PhysicalUnit: 3
@@ -127,14 +128,15 @@ RectTransform:
127128
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
128129
m_LocalPosition: {x: 0, y: 0, z: 0}
129130
m_LocalScale: {x: 1, y: 1, z: 1}
131+
m_ConstrainProportionsScale: 0
130132
m_Children: []
131133
m_Father: {fileID: 5075973321638144936}
132134
m_RootOrder: 0
133135
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
134136
m_AnchorMin: {x: 0, y: 0}
135137
m_AnchorMax: {x: 0, y: 0}
136138
m_AnchoredPosition: {x: 40, y: 40}
137-
m_SizeDelta: {x: 240, y: 400}
139+
m_SizeDelta: {x: 400, y: 400}
138140
m_Pivot: {x: 0, y: 0}
139141
--- !u!114 &3464894946384537378
140142
MonoBehaviour:

Assets/BossRoom/Scripts/Infrastructure/Editor/NetworkLatencyWarning.cs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using TMPro;
23
using UnityEngine;
34
using UnityEngine.UI;
45
using Unity.Netcode;
@@ -10,7 +11,7 @@ namespace Unity.Multiplayer.Samples.BossRoom.Editor
1011
{
1112
public class NetworkLatencyWarning : MonoBehaviour
1213
{
13-
Text m_LatencyText;
14+
TextMeshProUGUI m_LatencyText;
1415
bool m_LatencyTextCreated;
1516

1617
Color m_TextColor = Color.red;
@@ -66,19 +67,7 @@ void CreateLatencyText()
6667
Assert.IsNotNull(NetworkOverlay.Instance,
6768
"No NetworkOverlay object part of scene. Add NetworkOverlay prefab to bootstrap scene!");
6869

69-
var statUI = new GameObject("UI Latency Warning Text");
70-
71-
m_LatencyText = statUI.AddComponent<Text>();
72-
m_LatencyText.font = Font.CreateDynamicFontFromOSFont("Arial", 24);
73-
m_LatencyText.horizontalOverflow = HorizontalWrapMode.Overflow;
74-
m_LatencyText.alignment = TextAnchor.MiddleLeft;
75-
m_LatencyText.raycastTarget = false;
76-
m_LatencyText.resizeTextForBestFit = true;
77-
78-
m_LatencyText.text = "Network Latency Enabled";
79-
80-
var statUIRectTransform = statUI.GetComponent<RectTransform>();
81-
NetworkOverlay.Instance.AddToUI(statUIRectTransform);
70+
NetworkOverlay.Instance.AddTextToUI("UI Latency Warning Text", "Network Latency Enabled", out m_LatencyText);
8271
}
8372
}
8473
}

Assets/BossRoom/Scripts/Infrastructure/Editor/NetworkOverlay.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using TMPro;
12
using UnityEngine;
23
using UnityEngine.UI;
34

@@ -18,6 +19,21 @@ void Awake()
1819
DontDestroyOnLoad(this);
1920
}
2021

22+
public void AddTextToUI(string gameObjectName, string defaultText, out TextMeshProUGUI textComponent)
23+
{
24+
var rootGO = new GameObject(gameObjectName);
25+
textComponent = rootGO.AddComponent<TextMeshProUGUI>();
26+
textComponent.fontSize = 28;
27+
textComponent.text = defaultText;
28+
textComponent.horizontalAlignment = HorizontalAlignmentOptions.Left;
29+
textComponent.verticalAlignment = VerticalAlignmentOptions.Middle;
30+
textComponent.raycastTarget = false;
31+
textComponent.autoSizeTextContainer = true;
32+
33+
var rectTransform = rootGO.GetComponent<RectTransform>();
34+
AddToUI(rectTransform);
35+
}
36+
2137
public void AddToUI(RectTransform displayTransform)
2238
{
2339
if (m_VerticalLayoutTransform == null)
@@ -28,6 +44,7 @@ public void AddToUI(RectTransform displayTransform)
2844
displayTransform.sizeDelta = new Vector2(100f, 24f);
2945
displayTransform.SetParent(m_VerticalLayoutTransform);
3046
displayTransform.SetAsFirstSibling();
47+
displayTransform.localScale = Vector3.one;
3148
}
3249

3350
void CreateDebugCanvas()

Assets/BossRoom/Scripts/Infrastructure/NetworkStats.cs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,17 @@ public ExponentialMovingAverageCalculator(float average)
4242
const float k_PingIntervalSeconds = 0.1f;
4343
const float k_MaxWindowSize = k_MaxWindowSizeSeconds / k_PingIntervalSeconds;
4444

45+
// Some games are less sensitive to latency than others. For fast-paced games, latency above 100ms becomes a challenge for players while for others 500ms is fine. It's up to you to establish those thresholds.
46+
const float k_StrugglingNetworkConditionsRTTThreshold = 130;
47+
const float k_BadNetworkConditionsRTTThreshold = 200;
48+
4549
ExponentialMovingAverageCalculator m_BossRoomRTT = new ExponentialMovingAverageCalculator(0);
4650
ExponentialMovingAverageCalculator m_UtpRTT = new ExponentialMovingAverageCalculator(0);
4751

4852
float m_LastPingTime;
4953
TextMeshProUGUI m_TextStat;
5054
TextMeshProUGUI m_TextHostType;
55+
TextMeshProUGUI m_TextBadNetworkConditions;
5156

5257
// When receiving pong client RPCs, we need to know when the initiating ping sent it so we can calculate its individual RTT
5358
int m_CurrentRTTPingId;
@@ -86,23 +91,9 @@ void CreateNetworkStatsText()
8691
"No NetworkOverlay object part of scene. Add NetworkOverlay prefab to bootstrap scene!");
8792

8893
string hostType = IsHost ? "Host" : IsClient ? "Client" : "Unknown";
89-
InitializeTextLine($"Type: {hostType}", out m_TextHostType);
90-
InitializeTextLine("No Stat", out m_TextStat);
91-
}
92-
93-
void InitializeTextLine(string defaultText, out TextMeshProUGUI textComponent)
94-
{
95-
var rootGO = new GameObject("UI Stat Text");
96-
textComponent = rootGO.AddComponent<TextMeshProUGUI>();
97-
textComponent.fontSize = 24;
98-
textComponent.text = defaultText;
99-
textComponent.horizontalAlignment = HorizontalAlignmentOptions.Left;
100-
textComponent.verticalAlignment = VerticalAlignmentOptions.Middle;
101-
textComponent.raycastTarget = false;
102-
textComponent.autoSizeTextContainer = true;
103-
104-
var rectTransform = rootGO.GetComponent<RectTransform>();
105-
Editor.NetworkOverlay.Instance.AddToUI(rectTransform);
94+
Editor.NetworkOverlay.Instance.AddTextToUI("UI Host Type Text", $"Type: {hostType}", out m_TextHostType);
95+
Editor.NetworkOverlay.Instance.AddTextToUI("UI Stat Text", "No Stat", out m_TextStat);
96+
Editor.NetworkOverlay.Instance.AddTextToUI("UI Bad Conditions Text", "", out m_TextBadNetworkConditions);
10697
}
10798

10899
void FixedUpdate()
@@ -124,6 +115,28 @@ void FixedUpdate()
124115
if (m_TextStat != null)
125116
{
126117
m_TextToDisplay = $"RTT: {(m_BossRoomRTT.Average * 1000).ToString("0")} ms;\nUTP RTT {m_UtpRTT.Average.ToString("0")} ms";
118+
if (m_UtpRTT.Average > k_BadNetworkConditionsRTTThreshold)
119+
{
120+
m_TextStat.color = Color.red;
121+
}
122+
else if (m_UtpRTT.Average > k_StrugglingNetworkConditionsRTTThreshold)
123+
{
124+
m_TextStat.color = Color.yellow;
125+
}
126+
else
127+
{
128+
m_TextStat.color = Color.white;
129+
}
130+
}
131+
132+
if (m_TextBadNetworkConditions != null)
133+
{
134+
// Right now, we only base this warning on UTP's RTT metric, but in the future we could watch for packet loss as well, or other metrics.
135+
// This could be a simple icon instead of doing heavy string manipulations.
136+
m_TextBadNetworkConditions.text = m_UtpRTT.Average > k_BadNetworkConditionsRTTThreshold ? "Bad Network Conditions Detected!" : "";
137+
var color = Color.red;
138+
color.a = Mathf.PingPong(Time.time, 1f);
139+
m_TextBadNetworkConditions.color = color;
127140
}
128141
}
129142
else

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
99
## [Unreleased] - yyyy-mm-dd
1010

1111
### Added
12+
feat: bad network conditions warning [MTT-3242] (#632)
1213
feat: adding RNSM (Runtime Network Stats Monitor) to boss room [MTT-3267] (#621)
1314
Added basic automated testing and CI (#484) (#487) (#639)
1415
feat: connection feedback + IP connection window [MTT-2315] [MTT-3234] (#613)

0 commit comments

Comments
 (0)