Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
1 change: 1 addition & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
- Fixed `NetworkAnimator` issue where it was not taking the animation speed or state speed multiplier into consideration. (#1946)
- Fixed `NetworkAnimator` issue where it was not properly synchronizing late joining clients if they joined while `Animator` was transitioning between states. (#1946)
- Fixed `NetworkAnimator` issue where the server was not relaying changes to non-owner clients when a client was the owner. (#1946)
- Fixed issue where the `PacketLoss` metric for tools would return the packet loss over a connection lifetime instead of a single frame. (#2004)

## [1.0.0-pre.9] - 2022-05-10

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,15 @@ public struct SimulatorParameters
PacketDropRate = 0
};

private struct PacketLossCache
{
public int PacketsReceived;
public int PacketsDropped;
public float PacketLoss;
};

private PacketLossCache m_PacketLossCache = new PacketLossCache();

private State m_State = State.Disconnected;
private NetworkDriver m_Driver;
private NetworkSettings m_NetworkSettings;
Expand Down Expand Up @@ -839,11 +848,22 @@ private float ExtractPacketLoss(NetworkConnection networkConnection)
{
var sharedContext = (ReliableUtility.SharedContext*)sharedBuffer.GetUnsafePtr();

var packetReceived = (float)sharedContext->stats.PacketsReceived;
var packetDropped = (float)sharedContext->stats.PacketsDropped;
var packetLoss = packetReceived > 0 ? packetDropped / packetReceived : 0;
var packetReceivedDelta = (float)(sharedContext->stats.PacketsReceived - m_PacketLossCache.PacketsReceived);
var packetDroppedDelta = (float)(sharedContext->stats.PacketsDropped - m_PacketLossCache.PacketsDropped);

// There can be multiple update happening in a single frame where no packets have transitioned
// In those situation we want to return the last packet loss value instead of 0 to avoid invalid swings
if (packetDroppedDelta == 0 && packetReceivedDelta == 0)
{
return m_PacketLossCache.PacketLoss;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to return 0 in this case? It would mean that you don't need to store the previous value 🤔

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question, maybe what you have is already the best approach

}

m_PacketLossCache.PacketsReceived = sharedContext->stats.PacketsReceived;
m_PacketLossCache.PacketsDropped = sharedContext->stats.PacketsDropped;

m_PacketLossCache.PacketLoss = packetReceivedDelta > 0 ? packetDroppedDelta / packetReceivedDelta : 0;

return packetLoss;
return m_PacketLossCache.PacketLoss;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class PacketLossMetricsTests : NetcodeIntegrationTest
{
protected override int NumberOfClients => 1;
private readonly int m_PacketLossRate = 25;
private int m_DropInterval = 5;
private readonly int m_PacketLossRangeDelta = 5;

public PacketLossMetricsTests()
: base(HostOrServer.Server)
Expand Down Expand Up @@ -57,11 +57,12 @@ public IEnumerator TrackPacketLossAsServer()
[UnityTest]
public IEnumerator TrackPacketLossAsClient()
{
double packetLossRate = m_PacketLossRate/100d;
double packetLossRateMinRange = (m_PacketLossRate-m_PacketLossRangeDelta) / 100d;
double packetLossRateMaxrange = (m_PacketLossRate + m_PacketLossRangeDelta) / 100d;
var clientNetworkManager = m_ClientNetworkManagers[0];
var waitForPacketLossMetric = new WaitForGaugeMetricValues((clientNetworkManager.NetworkMetrics as NetworkMetrics).Dispatcher,
NetworkMetricTypes.PacketLoss,
metric => Math.Abs(metric - packetLossRate) < Double.Epsilon);
metric => packetLossRateMinRange <= metric && metric <= packetLossRateMaxrange);

for (int i = 0; i < 1000; ++i)
{
Expand All @@ -75,7 +76,7 @@ public IEnumerator TrackPacketLossAsClient()
yield return waitForPacketLossMetric.WaitForMetricsReceived();

var packetLossValue = waitForPacketLossMetric.AssertMetricValueHaveBeenFound();
Assert.AreEqual(packetLossRate, packetLossValue);
Assert.That(packetLossValue, Is.InRange(packetLossRateMinRange, packetLossRateMaxrange));
}
}
}
Expand Down