diff --git a/Source/Editor/Windows/Profiler/Network.cs b/Source/Editor/Windows/Profiler/Network.cs
new file mode 100644
index 000000000..ef4f2f7ea
--- /dev/null
+++ b/Source/Editor/Windows/Profiler/Network.cs
@@ -0,0 +1,87 @@
+// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
+
+using FlaxEngine;
+using FlaxEngine.GUI;
+
+namespace FlaxEditor.Windows.Profiler
+{
+ ///
+ /// The network profiling mode.
+ ///
+ ///
+ internal sealed class Network : ProfilerMode
+ {
+ private readonly SingleChart _dataSentChart;
+ private readonly SingleChart _dataReceivedChart;
+ private FlaxEngine.Networking.NetworkDriverStats _prevStats;
+
+ public Network()
+ : base("Network")
+ {
+ // Layout
+ var panel = new Panel(ScrollBars.Vertical)
+ {
+ AnchorPreset = AnchorPresets.StretchAll,
+ Offsets = Margin.Zero,
+ Parent = this,
+ };
+ var layout = new VerticalPanel
+ {
+ AnchorPreset = AnchorPresets.HorizontalStretchTop,
+ Offsets = Margin.Zero,
+ IsScrollable = true,
+ Parent = panel,
+ };
+
+ // Charts
+ _dataSentChart = new SingleChart
+ {
+ Title = "Data Sent",
+ FormatSample = FormatSampleBytes,
+ Parent = layout,
+ };
+ _dataSentChart.SelectedSampleChanged += OnSelectedSampleChanged;
+ _dataReceivedChart = new SingleChart
+ {
+ Title = "Data Received",
+ FormatSample = FormatSampleBytes,
+ Parent = layout,
+ };
+ _dataReceivedChart.SelectedSampleChanged += OnSelectedSampleChanged;
+ }
+
+ private static string FormatSampleBytes(float v)
+ {
+ return (uint)v + " bytes";
+ }
+
+ ///
+ public override void Clear()
+ {
+ _dataSentChart.Clear();
+ _dataReceivedChart.Clear();
+ }
+
+ ///
+ public override void Update(ref SharedUpdateData sharedData)
+ {
+ var peer = FlaxEngine.Networking.NetworkManager.Peer;
+ if (peer == null)
+ {
+ _prevStats = new FlaxEngine.Networking.NetworkDriverStats();
+ return;
+ }
+ var stats = peer.NetworkDriver.GetStats();
+ _dataSentChart.AddSample(Mathf.Max((long)stats.TotalDataSent - (long)_prevStats.TotalDataSent, 0));
+ _dataReceivedChart.AddSample(Mathf.Max((long)stats.TotalDataReceived - (long)_prevStats.TotalDataReceived, 0));
+ _prevStats = stats;
+ }
+
+ ///
+ public override void UpdateView(int selectedFrame, bool showOnlyLastUpdateEvents)
+ {
+ _dataSentChart.SelectedSampleIndex = selectedFrame;
+ _dataReceivedChart.SelectedSampleIndex = selectedFrame;
+ }
+ }
+}
diff --git a/Source/Editor/Windows/Profiler/ProfilerWindow.cs b/Source/Editor/Windows/Profiler/ProfilerWindow.cs
index 4d1ad9ba1..d85cc159a 100644
--- a/Source/Editor/Windows/Profiler/ProfilerWindow.cs
+++ b/Source/Editor/Windows/Profiler/ProfilerWindow.cs
@@ -182,6 +182,7 @@ namespace FlaxEditor.Windows.Profiler
AddMode(new CPU());
AddMode(new GPU());
AddMode(new Memory());
+ AddMode(new Network());
// Init view
_frameIndex = -1;
diff --git a/Source/Engine/Networking/Drivers/ENetDriver.cpp b/Source/Engine/Networking/Drivers/ENetDriver.cpp
index adff7525a..9eac8a0f9 100644
--- a/Source/Engine/Networking/Drivers/ENetDriver.cpp
+++ b/Source/Engine/Networking/Drivers/ENetDriver.cpp
@@ -254,6 +254,8 @@ NetworkDriverStats ENetDriver::GetStats(NetworkConnection target)
if (peer)
{
stats.RTT = (float)peer->roundTripTime;
+ stats.TotalDataSent = peer->totalDataSent;
+ stats.TotalDataReceived = peer->totalDataReceived;
}
return stats;
}
diff --git a/Source/Engine/Networking/NetworkStats.h b/Source/Engine/Networking/NetworkStats.h
index eaa1daedb..d9ebd4d91 100644
--- a/Source/Engine/Networking/NetworkStats.h
+++ b/Source/Engine/Networking/NetworkStats.h
@@ -16,6 +16,16 @@ API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkDrive
/// The mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement. Also known as ping time.
///
API_FIELD() float RTT = 0.0f;
+
+ ///
+ /// Total amount of data bytes sent by this client.
+ ///
+ API_FIELD() uint32 TotalDataSent = 0;
+
+ ///
+ /// Total amount of data bytes received by this client.
+ ///
+ API_FIELD() uint32 TotalDataReceived = 0;
};
template<>