The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com). ## [1.6.0] - 2023-08-09 ### Added - Added a protected virtual method `NetworkTransform.OnInitialize(ref NetworkTransformState replicatedState)` that just returns the replicated state reference. ### Fixed - Fixed issue where invoking `NetworkManager.Shutdown` within `NetworkManager.OnClientStopped` or `NetworkManager.OnServerStopped` would force `NetworkManager.ShutdownInProgress` to remain true after completing the shutdown process. (#2661) - Fixed issue with client synchronization of position when using half precision and the delta position reaches the maximum value and is collapsed on the host prior to being forwarded to the non-owner clients. (#2636) - Fixed issue with scale not synchronizing properly depending upon the spawn order of NetworkObjects. (#2636) - Fixed issue position was not properly transitioning between ownership changes with an owner authoritative NetworkTransform. (#2636) - Fixed issue where a late joining non-owner client could update an owner authoritative NetworkTransform if ownership changed without any updates to position prior to the non-owner client joining. (#2636) ### Changed
112 lines
3.9 KiB
C#
112 lines
3.9 KiB
C#
#if MULTIPLAYER_TOOLS
|
|
using System;
|
|
using System.Collections;
|
|
using NUnit.Framework;
|
|
using Unity.Collections;
|
|
using Unity.Multiplayer.Tools.MetricTypes;
|
|
using Unity.Multiplayer.Tools.NetStats;
|
|
using Unity.Netcode.TestHelpers.Runtime.Metrics;
|
|
using UnityEngine.TestTools;
|
|
|
|
namespace Unity.Netcode.RuntimeTests.Metrics
|
|
{
|
|
internal class TransportBytesMetricsTests : SingleClientMetricTestBase
|
|
{
|
|
// Header is dynamically sized due to packing, will be 2 bytes for all test messages.
|
|
private const int k_MessageHeaderSize = 2;
|
|
private static readonly long k_MessageOverhead = 8 + FastBufferWriter.GetWriteSize<NetworkBatchHeader>() + k_MessageHeaderSize;
|
|
|
|
[UnityTest]
|
|
public IEnumerator TrackTotalNumberOfBytesSent()
|
|
{
|
|
var messageName = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
|
var writer = new FastBufferWriter(1300, Allocator.Temp);
|
|
var observer = new TotalBytesObserver(ClientMetrics.Dispatcher, NetworkMetricTypes.TotalBytesReceived);
|
|
try
|
|
{
|
|
writer.WriteValueSafe(messageName);
|
|
|
|
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), Client.LocalClientId, writer);
|
|
}
|
|
finally
|
|
{
|
|
writer.Dispose();
|
|
}
|
|
|
|
var nbFrames = 0;
|
|
while (!observer.Found || nbFrames < 10)
|
|
{
|
|
yield return null;
|
|
nbFrames++;
|
|
}
|
|
|
|
Assert.True(observer.Found);
|
|
Assert.AreEqual(((FastBufferWriter.GetWriteSize(messageName) + k_MessageOverhead) + 7) & ~7, observer.Value);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TrackTotalNumberOfBytesReceived()
|
|
{
|
|
var messageName = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
|
var writer = new FastBufferWriter(1300, Allocator.Temp);
|
|
var observer = new TotalBytesObserver(ClientMetrics.Dispatcher, NetworkMetricTypes.TotalBytesReceived);
|
|
try
|
|
{
|
|
writer.WriteValueSafe(messageName);
|
|
|
|
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), Client.LocalClientId, writer);
|
|
}
|
|
finally
|
|
{
|
|
writer.Dispose();
|
|
}
|
|
|
|
var nbFrames = 0;
|
|
while (!observer.Found || nbFrames < 10)
|
|
{
|
|
yield return null;
|
|
nbFrames++;
|
|
}
|
|
|
|
Assert.True(observer.Found);
|
|
Assert.AreEqual(((FastBufferWriter.GetWriteSize(messageName) + k_MessageOverhead) + 7) & ~7, observer.Value);
|
|
}
|
|
|
|
private class TotalBytesObserver : IMetricObserver
|
|
{
|
|
private readonly DirectionalMetricInfo m_MetricInfo;
|
|
|
|
public TotalBytesObserver(IMetricDispatcher dispatcher, DirectionalMetricInfo metricInfo)
|
|
{
|
|
m_MetricInfo = metricInfo;
|
|
|
|
dispatcher.RegisterObserver(this);
|
|
}
|
|
|
|
public bool Found { get; private set; }
|
|
|
|
public long Value { get; private set; }
|
|
|
|
private int m_BytesFoundCounter;
|
|
private long m_TotalBytes;
|
|
|
|
public void Observe(MetricCollection collection)
|
|
{
|
|
if (collection.TryGetCounter(m_MetricInfo.Id, out var counter) && counter.Value > 0)
|
|
{
|
|
// Don't assign another observed value once one is already observed
|
|
if (!Found)
|
|
{
|
|
Found = true;
|
|
Value = counter.Value;
|
|
m_TotalBytes += ((counter.Value + 7) & ~7);
|
|
m_BytesFoundCounter++;
|
|
UnityEngine.Debug.Log($"[{m_BytesFoundCounter}] Bytes Observed {counter.Value} | Total Bytes Observed: {m_TotalBytes}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|