com.unity.netcode.gameobjects@1.0.0-pre.8
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.0.0-pre.8] - 2022-04-27 ### Changed - `unmanaged` structs are no longer universally accepted as RPC parameters because some structs (i.e., structs with pointers in them, such as `NativeList<T>`) can't be supported by the default memcpy struct serializer. Structs that are intended to be serialized across the network must add `INetworkSerializeByMemcpy` to the interface list (i.e., `struct Foo : INetworkSerializeByMemcpy`). This interface is empty and just serves to mark the struct as compatible with memcpy serialization. For external structs you can't edit, you can pass them to RPCs by wrapping them in `ForceNetworkSerializeByMemcpy<T>`. (#1901) ### Removed - Removed `SIPTransport` (#1870) - Removed `ClientNetworkTransform` from the package samples and moved to Boss Room's Utilities package which can be found [here](https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop/blob/main/Packages/com.unity.multiplayer.samples.coop/Utilities/Net/ClientAuthority/ClientNetworkTransform.cs). ### Fixed - Fixed `NetworkTransform` generating false positive rotation delta checks when rolling over between 0 and 360 degrees. (#1890) - Fixed client throwing an exception if it has messages in the outbound queue when processing the `NetworkEvent.Disconnect` event and is using UTP. (#1884) - Fixed issue during client synchronization if 'ValidateSceneBeforeLoading' returned false it would halt the client synchronization process resulting in a client that was approved but not synchronized or fully connected with the server. (#1883) - Fixed an issue where UNetTransport.StartServer would return success even if the underlying transport failed to start (#854) - Passing generic types to RPCs no longer causes a native crash (#1901) - Fixed an issue where calling `Shutdown` on a `NetworkManager` that was already shut down would cause an immediate shutdown the next time it was started (basically the fix makes `Shutdown` idempotent). (#1877)
This commit is contained in:
@@ -340,8 +340,8 @@ MonoBehaviour:
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 593a2fe42fa9d37498c96f9a383b6521, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
DontDestroy: 1
|
||||
RunInBackground: 1
|
||||
LogLevel: 1
|
||||
@@ -356,7 +356,7 @@ MonoBehaviour:
|
||||
TickRate: 30
|
||||
ClientConnectionBufferTimeout: 10
|
||||
ConnectionApproval: 0
|
||||
ConnectionData:
|
||||
ConnectionData:
|
||||
EnableTimeResync: 0
|
||||
TimeResyncInterval: 30
|
||||
EnableNetworkVariable: 1
|
||||
@@ -367,5 +367,5 @@ MonoBehaviour:
|
||||
NetworkIdRecycleDelay: 120
|
||||
RpcHashSize: 0
|
||||
LoadSceneTimeOut: 120
|
||||
MessageBufferTimeout: 20
|
||||
SpawnTimeout: 20
|
||||
EnableNetworkLogs: 1
|
||||
|
||||
@@ -4,6 +4,7 @@ using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Unity.Netcode.EditorTests
|
||||
{
|
||||
@@ -16,13 +17,25 @@ namespace Unity.Netcode.EditorTests
|
||||
{
|
||||
var execAssembly = Assembly.GetExecutingAssembly();
|
||||
var packagePath = UnityEditor.PackageManager.PackageInfo.FindForAssembly(execAssembly).assetPath;
|
||||
var buildTarget = EditorUserBuildSettings.activeBuildTarget;
|
||||
var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget);
|
||||
var buildTargetSupported = BuildPipeline.IsBuildTargetSupported(buildTargetGroup, buildTarget);
|
||||
|
||||
var buildReport = BuildPipeline.BuildPlayer(
|
||||
new[] { Path.Combine(packagePath, DefaultBuildScenePath) },
|
||||
Path.Combine(Path.GetDirectoryName(Application.dataPath), "Builds", nameof(BuildTests)),
|
||||
EditorUserBuildSettings.activeBuildTarget,
|
||||
buildTarget,
|
||||
BuildOptions.None
|
||||
);
|
||||
Assert.AreEqual(BuildResult.Succeeded, buildReport.summary.result);
|
||||
|
||||
if (buildTargetSupported)
|
||||
{
|
||||
Assert.AreEqual(BuildResult.Succeeded, buildReport.summary.result);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAssert.Expect(LogType.Error, "Error building player because build target was unsupported");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Unity.Netcode.EditorTests
|
||||
{
|
||||
public class MessageReceivingTests
|
||||
{
|
||||
private struct TestMessage : INetworkMessage
|
||||
private struct TestMessage : INetworkMessage, INetworkSerializeByMemcpy
|
||||
{
|
||||
public int A;
|
||||
public int B;
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Unity.Netcode.EditorTests
|
||||
{
|
||||
public class MessageRegistrationTests
|
||||
{
|
||||
private struct TestMessageOne : INetworkMessage
|
||||
private struct TestMessageOne : INetworkMessage, INetworkSerializeByMemcpy
|
||||
{
|
||||
public int A;
|
||||
public int B;
|
||||
@@ -25,7 +25,7 @@ namespace Unity.Netcode.EditorTests
|
||||
}
|
||||
}
|
||||
|
||||
private struct TestMessageTwo : INetworkMessage
|
||||
private struct TestMessageTwo : INetworkMessage, INetworkSerializeByMemcpy
|
||||
{
|
||||
public int A;
|
||||
public int B;
|
||||
@@ -64,7 +64,7 @@ namespace Unity.Netcode.EditorTests
|
||||
}
|
||||
}
|
||||
|
||||
private struct TestMessageThree : INetworkMessage
|
||||
private struct TestMessageThree : INetworkMessage, INetworkSerializeByMemcpy
|
||||
{
|
||||
public int A;
|
||||
public int B;
|
||||
@@ -97,7 +97,7 @@ namespace Unity.Netcode.EditorTests
|
||||
};
|
||||
}
|
||||
}
|
||||
private struct TestMessageFour : INetworkMessage
|
||||
private struct TestMessageFour : INetworkMessage, INetworkSerializeByMemcpy
|
||||
{
|
||||
public int A;
|
||||
public int B;
|
||||
@@ -173,8 +173,6 @@ namespace Unity.Netcode.EditorTests
|
||||
MessagingSystem.MessageHandler handlerThree = MessagingSystem.ReceiveMessage<TestMessageThree>;
|
||||
MessagingSystem.MessageHandler handlerFour = MessagingSystem.ReceiveMessage<TestMessageFour>;
|
||||
|
||||
var foundHandlerOne = systemOne.MessageHandlers[systemOne.GetMessageType(typeof(TestMessageOne))];
|
||||
|
||||
Assert.AreEqual(handlerOne, systemOne.MessageHandlers[systemOne.GetMessageType(typeof(TestMessageOne))]);
|
||||
Assert.AreEqual(handlerTwo, systemOne.MessageHandlers[systemOne.GetMessageType(typeof(TestMessageTwo))]);
|
||||
Assert.AreEqual(handlerThree, systemTwo.MessageHandlers[systemTwo.GetMessageType(typeof(TestMessageThree))]);
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Unity.Netcode.EditorTests
|
||||
{
|
||||
public class MessageSendingTests
|
||||
{
|
||||
private struct TestMessage : INetworkMessage
|
||||
private struct TestMessage : INetworkMessage, INetworkSerializeByMemcpy
|
||||
{
|
||||
public int A;
|
||||
public int B;
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Unity.Netcode.EditorTests
|
||||
C
|
||||
};
|
||||
|
||||
protected struct TestStruct
|
||||
protected struct TestStruct : INetworkSerializeByMemcpy
|
||||
{
|
||||
public byte A;
|
||||
public short B;
|
||||
@@ -80,7 +80,6 @@ namespace Unity.Netcode.EditorTests
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
protected abstract void RunTypeTest<T>(T valueToTest) where T : unmanaged;
|
||||
|
||||
protected abstract void RunTypeTestSafe<T>(T valueToTest) where T : unmanaged;
|
||||
@@ -114,143 +113,144 @@ namespace Unity.Netcode.EditorTests
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private void RunTestWithWriteType<T>(T val, WriteType wt, FastBufferWriter.ForPrimitives _ = default) where T : unmanaged
|
||||
{
|
||||
switch (wt)
|
||||
{
|
||||
case WriteType.WriteDirect:
|
||||
RunTypeTest(val);
|
||||
break;
|
||||
case WriteType.WriteSafe:
|
||||
RunTypeTestSafe(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void BaseTypeTest(Type testType, WriteType writeType)
|
||||
{
|
||||
var random = new Random();
|
||||
|
||||
void RunTypeTestLocal<T>(T val, WriteType wt) where T : unmanaged
|
||||
{
|
||||
switch (wt)
|
||||
{
|
||||
case WriteType.WriteDirect:
|
||||
RunTypeTest(val);
|
||||
break;
|
||||
case WriteType.WriteSafe:
|
||||
RunTypeTestSafe(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (testType == typeof(byte))
|
||||
{
|
||||
RunTypeTestLocal((byte)random.Next(), writeType);
|
||||
RunTestWithWriteType((byte)random.Next(), writeType);
|
||||
}
|
||||
else if (testType == typeof(sbyte))
|
||||
{
|
||||
RunTypeTestLocal((sbyte)random.Next(), writeType);
|
||||
RunTestWithWriteType((sbyte)random.Next(), writeType);
|
||||
}
|
||||
else if (testType == typeof(short))
|
||||
{
|
||||
RunTypeTestLocal((short)random.Next(), writeType);
|
||||
RunTestWithWriteType((short)random.Next(), writeType);
|
||||
}
|
||||
else if (testType == typeof(ushort))
|
||||
{
|
||||
RunTypeTestLocal((ushort)random.Next(), writeType);
|
||||
RunTestWithWriteType((ushort)random.Next(), writeType);
|
||||
}
|
||||
else if (testType == typeof(int))
|
||||
{
|
||||
RunTypeTestLocal((int)random.Next(), writeType);
|
||||
RunTestWithWriteType((int)random.Next(), writeType);
|
||||
}
|
||||
else if (testType == typeof(uint))
|
||||
{
|
||||
RunTypeTestLocal((uint)random.Next(), writeType);
|
||||
RunTestWithWriteType((uint)random.Next(), writeType);
|
||||
}
|
||||
else if (testType == typeof(long))
|
||||
{
|
||||
RunTypeTestLocal(((long)random.Next() << 32) + random.Next(), writeType);
|
||||
RunTestWithWriteType(((long)random.Next() << 32) + random.Next(), writeType);
|
||||
}
|
||||
else if (testType == typeof(ulong))
|
||||
{
|
||||
RunTypeTestLocal(((ulong)random.Next() << 32) + (ulong)random.Next(), writeType);
|
||||
RunTestWithWriteType(((ulong)random.Next() << 32) + (ulong)random.Next(), writeType);
|
||||
}
|
||||
else if (testType == typeof(bool))
|
||||
{
|
||||
RunTypeTestLocal(true, writeType);
|
||||
RunTestWithWriteType(true, writeType);
|
||||
}
|
||||
else if (testType == typeof(char))
|
||||
{
|
||||
RunTypeTestLocal('a', writeType);
|
||||
RunTypeTestLocal('\u263a', writeType);
|
||||
RunTestWithWriteType('a', writeType);
|
||||
RunTestWithWriteType('\u263a', writeType);
|
||||
}
|
||||
else if (testType == typeof(float))
|
||||
{
|
||||
RunTypeTestLocal((float)random.NextDouble(), writeType);
|
||||
RunTestWithWriteType((float)random.NextDouble(), writeType);
|
||||
}
|
||||
else if (testType == typeof(double))
|
||||
{
|
||||
RunTypeTestLocal(random.NextDouble(), writeType);
|
||||
RunTestWithWriteType(random.NextDouble(), writeType);
|
||||
}
|
||||
else if (testType == typeof(ByteEnum))
|
||||
{
|
||||
RunTypeTestLocal(ByteEnum.C, writeType);
|
||||
RunTestWithWriteType(ByteEnum.C, writeType);
|
||||
}
|
||||
else if (testType == typeof(SByteEnum))
|
||||
{
|
||||
RunTypeTestLocal(SByteEnum.C, writeType);
|
||||
RunTestWithWriteType(SByteEnum.C, writeType);
|
||||
}
|
||||
else if (testType == typeof(ShortEnum))
|
||||
{
|
||||
RunTypeTestLocal(ShortEnum.C, writeType);
|
||||
RunTestWithWriteType(ShortEnum.C, writeType);
|
||||
}
|
||||
else if (testType == typeof(UShortEnum))
|
||||
{
|
||||
RunTypeTestLocal(UShortEnum.C, writeType);
|
||||
RunTestWithWriteType(UShortEnum.C, writeType);
|
||||
}
|
||||
else if (testType == typeof(IntEnum))
|
||||
{
|
||||
RunTypeTestLocal(IntEnum.C, writeType);
|
||||
RunTestWithWriteType(IntEnum.C, writeType);
|
||||
}
|
||||
else if (testType == typeof(UIntEnum))
|
||||
{
|
||||
RunTypeTestLocal(UIntEnum.C, writeType);
|
||||
RunTestWithWriteType(UIntEnum.C, writeType);
|
||||
}
|
||||
else if (testType == typeof(LongEnum))
|
||||
{
|
||||
RunTypeTestLocal(LongEnum.C, writeType);
|
||||
RunTestWithWriteType(LongEnum.C, writeType);
|
||||
}
|
||||
else if (testType == typeof(ULongEnum))
|
||||
{
|
||||
RunTypeTestLocal(ULongEnum.C, writeType);
|
||||
RunTestWithWriteType(ULongEnum.C, writeType);
|
||||
}
|
||||
else if (testType == typeof(Vector2))
|
||||
{
|
||||
RunTypeTestLocal(new Vector2((float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
RunTestWithWriteType(new Vector2((float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
}
|
||||
else if (testType == typeof(Vector3))
|
||||
{
|
||||
RunTypeTestLocal(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
RunTestWithWriteType(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
}
|
||||
else if (testType == typeof(Vector4))
|
||||
{
|
||||
RunTypeTestLocal(new Vector4((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
RunTestWithWriteType(new Vector4((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
}
|
||||
else if (testType == typeof(Quaternion))
|
||||
{
|
||||
RunTypeTestLocal(new Quaternion((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
RunTestWithWriteType(new Quaternion((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
}
|
||||
else if (testType == typeof(Color))
|
||||
{
|
||||
RunTypeTestLocal(new Color((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
RunTestWithWriteType(new Color((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
}
|
||||
else if (testType == typeof(Color32))
|
||||
{
|
||||
RunTypeTestLocal(new Color32((byte)random.Next(), (byte)random.Next(), (byte)random.Next(), (byte)random.Next()), writeType);
|
||||
RunTestWithWriteType(new Color32((byte)random.Next(), (byte)random.Next(), (byte)random.Next(), (byte)random.Next()), writeType);
|
||||
}
|
||||
else if (testType == typeof(Ray))
|
||||
{
|
||||
RunTypeTestLocal(new Ray(
|
||||
RunTestWithWriteType(new Ray(
|
||||
new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()),
|
||||
new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), writeType);
|
||||
}
|
||||
else if (testType == typeof(Ray2D))
|
||||
{
|
||||
RunTypeTestLocal(new Ray2D(
|
||||
RunTestWithWriteType(new Ray2D(
|
||||
new Vector2((float)random.NextDouble(), (float)random.NextDouble()),
|
||||
new Vector2((float)random.NextDouble(), (float)random.NextDouble())), writeType);
|
||||
}
|
||||
else if (testType == typeof(TestStruct))
|
||||
{
|
||||
RunTypeTestLocal(GetTestStruct(), writeType);
|
||||
RunTestWithWriteType(GetTestStruct(), writeType);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
@@ -51,6 +52,184 @@ namespace Unity.Netcode.EditorTests
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
private void RunWriteMethod<T>(string methodName, FastBufferWriter writer, in T value) where T : unmanaged
|
||||
{
|
||||
MethodInfo method = typeof(FastBufferWriter).GetMethod(methodName, new[] { typeof(T).MakeByRefType() });
|
||||
if (method == null)
|
||||
{
|
||||
foreach (var candidateMethod in typeof(FastBufferWriter).GetMethods())
|
||||
{
|
||||
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
|
||||
{
|
||||
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (candidateMethod.GetParameters()[0].ParameterType.IsArray)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
method = candidateMethod.MakeGenericMethod(typeof(T));
|
||||
break;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert.NotNull(method);
|
||||
|
||||
object[] args = new object[method.GetParameters().Length];
|
||||
args[0] = value;
|
||||
for (var i = 1; i < args.Length; ++i)
|
||||
{
|
||||
args[i] = method.GetParameters()[i].DefaultValue;
|
||||
}
|
||||
method.Invoke(writer, args);
|
||||
}
|
||||
|
||||
private void RunWriteMethod<T>(string methodName, FastBufferWriter writer, in T[] value) where T : unmanaged
|
||||
{
|
||||
MethodInfo method = typeof(FastBufferWriter).GetMethod(methodName, new[] { typeof(T[]) });
|
||||
if (method == null)
|
||||
{
|
||||
foreach (var candidateMethod in typeof(FastBufferWriter).GetMethods())
|
||||
{
|
||||
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
|
||||
{
|
||||
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!candidateMethod.GetParameters()[0].ParameterType.IsArray)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
method = candidateMethod.MakeGenericMethod(typeof(T));
|
||||
break;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert.NotNull(method);
|
||||
|
||||
object[] args = new object[method.GetParameters().Length];
|
||||
args[0] = value;
|
||||
for (var i = 1; i < args.Length; ++i)
|
||||
{
|
||||
args[i] = method.GetParameters()[i].DefaultValue;
|
||||
}
|
||||
method.Invoke(writer, args);
|
||||
}
|
||||
|
||||
private void RunReadMethod<T>(string methodName, FastBufferReader reader, out T value) where T : unmanaged
|
||||
{
|
||||
MethodInfo method = typeof(FastBufferReader).GetMethod(methodName, new[] { typeof(T).MakeByRefType() });
|
||||
if (method == null)
|
||||
{
|
||||
foreach (var candidateMethod in typeof(FastBufferReader).GetMethods())
|
||||
{
|
||||
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
|
||||
{
|
||||
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (candidateMethod.GetParameters()[0].ParameterType.IsArray)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
method = candidateMethod.MakeGenericMethod(typeof(T));
|
||||
break;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
value = new T();
|
||||
|
||||
Assert.NotNull(method);
|
||||
|
||||
object[] args = new object[method.GetParameters().Length];
|
||||
args[0] = value;
|
||||
for (var i = 1; i < args.Length; ++i)
|
||||
{
|
||||
args[i] = method.GetParameters()[i].DefaultValue;
|
||||
}
|
||||
method.Invoke(reader, args);
|
||||
value = (T)args[0];
|
||||
}
|
||||
|
||||
private void RunReadMethod<T>(string methodName, FastBufferReader reader, out T[] value) where T : unmanaged
|
||||
{
|
||||
MethodInfo method = null;
|
||||
|
||||
try
|
||||
{
|
||||
method = typeof(FastBufferReader).GetMethod(methodName, new[] { typeof(T[]).MakeByRefType() });
|
||||
}
|
||||
catch (AmbiguousMatchException)
|
||||
{
|
||||
// skip.
|
||||
}
|
||||
if (method == null)
|
||||
{
|
||||
foreach (var candidateMethod in typeof(FastBufferReader).GetMethods())
|
||||
{
|
||||
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
|
||||
{
|
||||
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!candidateMethod.GetParameters()[0].ParameterType.HasElementType || !candidateMethod.GetParameters()[0].ParameterType.GetElementType().IsArray)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
method = candidateMethod.MakeGenericMethod(typeof(T));
|
||||
break;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert.NotNull(method);
|
||||
|
||||
value = new T[] { };
|
||||
|
||||
object[] args = new object[method.GetParameters().Length];
|
||||
args[0] = value;
|
||||
for (var i = 1; i < args.Length; ++i)
|
||||
{
|
||||
args[i] = method.GetParameters()[i].DefaultValue;
|
||||
}
|
||||
method.Invoke(reader, args);
|
||||
value = (T[])args[0];
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Generic Checks
|
||||
@@ -66,14 +245,14 @@ namespace Unity.Netcode.EditorTests
|
||||
|
||||
var failMessage = $"RunTypeTest failed with type {typeof(T)} and value {valueToTest}";
|
||||
|
||||
writer.WriteValue(valueToTest);
|
||||
RunWriteMethod(nameof(FastBufferWriter.WriteValue), writer, valueToTest);
|
||||
|
||||
var reader = CommonChecks(writer, valueToTest, writeSize, failMessage);
|
||||
|
||||
using (reader)
|
||||
{
|
||||
Assert.IsTrue(reader.TryBeginRead(FastBufferWriter.GetWriteSize<T>()));
|
||||
reader.ReadValue(out T result);
|
||||
RunReadMethod(nameof(FastBufferReader.ReadValue), reader, out T result);
|
||||
Assert.AreEqual(valueToTest, result);
|
||||
}
|
||||
}
|
||||
@@ -89,14 +268,14 @@ namespace Unity.Netcode.EditorTests
|
||||
|
||||
var failMessage = $"RunTypeTest failed with type {typeof(T)} and value {valueToTest}";
|
||||
|
||||
writer.WriteValueSafe(valueToTest);
|
||||
RunWriteMethod(nameof(FastBufferWriter.WriteValueSafe), writer, valueToTest);
|
||||
|
||||
|
||||
var reader = CommonChecks(writer, valueToTest, writeSize, failMessage);
|
||||
|
||||
using (reader)
|
||||
{
|
||||
reader.ReadValueSafe(out T result);
|
||||
RunReadMethod(nameof(FastBufferReader.ReadValueSafe), reader, out T result);
|
||||
Assert.AreEqual(valueToTest, result);
|
||||
}
|
||||
}
|
||||
@@ -121,7 +300,7 @@ namespace Unity.Netcode.EditorTests
|
||||
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
|
||||
Assert.IsTrue(writer.TryBeginWrite(writeSize + 2), "Writer denied write permission");
|
||||
|
||||
writer.WriteValue(valueToTest);
|
||||
RunWriteMethod(nameof(FastBufferWriter.WriteValue), writer, valueToTest);
|
||||
|
||||
WriteCheckBytes(writer, writeSize);
|
||||
|
||||
@@ -131,7 +310,7 @@ namespace Unity.Netcode.EditorTests
|
||||
VerifyPositionAndLength(reader, writer.Length);
|
||||
|
||||
Assert.IsTrue(reader.TryBeginRead(writeSize));
|
||||
reader.ReadValue(out T[] result);
|
||||
RunReadMethod(nameof(FastBufferReader.ReadValue), reader, out T[] result);
|
||||
VerifyArrayEquality(valueToTest, result, 0);
|
||||
|
||||
VerifyCheckBytes(reader, writeSize);
|
||||
@@ -147,7 +326,7 @@ namespace Unity.Netcode.EditorTests
|
||||
{
|
||||
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
|
||||
|
||||
writer.WriteValueSafe(valueToTest);
|
||||
RunWriteMethod(nameof(FastBufferWriter.WriteValueSafe), writer, valueToTest);
|
||||
|
||||
WriteCheckBytes(writer, writeSize);
|
||||
|
||||
@@ -156,7 +335,7 @@ namespace Unity.Netcode.EditorTests
|
||||
{
|
||||
VerifyPositionAndLength(reader, writer.Length);
|
||||
|
||||
reader.ReadValueSafe(out T[] result);
|
||||
RunReadMethod(nameof(FastBufferReader.ReadValueSafe), reader, out T[] result);
|
||||
VerifyArrayEquality(valueToTest, result, 0);
|
||||
|
||||
VerifyCheckBytes(reader, writeSize);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
@@ -10,6 +11,7 @@ namespace Unity.Netcode.EditorTests
|
||||
{
|
||||
|
||||
#region Common Checks
|
||||
|
||||
private void WriteCheckBytes(FastBufferWriter writer, int writeSize, string failMessage = "")
|
||||
{
|
||||
Assert.IsTrue(writer.TryBeginWrite(2), "Writer denied write permission");
|
||||
@@ -63,9 +65,94 @@ namespace Unity.Netcode.EditorTests
|
||||
|
||||
VerifyTypedEquality(valueToTest, writer.GetUnsafePtr());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Generic Checks
|
||||
|
||||
private void RunMethod<T>(string methodName, FastBufferWriter writer, in T value) where T : unmanaged
|
||||
{
|
||||
MethodInfo method = typeof(FastBufferWriter).GetMethod(methodName, new[] { typeof(T).MakeByRefType() });
|
||||
if (method == null)
|
||||
{
|
||||
foreach (var candidateMethod in typeof(FastBufferWriter).GetMethods())
|
||||
{
|
||||
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
|
||||
{
|
||||
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (candidateMethod.GetParameters()[0].ParameterType.IsArray)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
method = candidateMethod.MakeGenericMethod(typeof(T));
|
||||
break;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert.NotNull(method);
|
||||
|
||||
object[] args = new object[method.GetParameters().Length];
|
||||
args[0] = value;
|
||||
for (var i = 1; i < args.Length; ++i)
|
||||
{
|
||||
args[i] = method.GetParameters()[i].DefaultValue;
|
||||
}
|
||||
method.Invoke(writer, args);
|
||||
}
|
||||
|
||||
private void RunMethod<T>(string methodName, FastBufferWriter writer, in T[] value) where T : unmanaged
|
||||
{
|
||||
MethodInfo method = typeof(FastBufferWriter).GetMethod(methodName, new[] { typeof(T[]) });
|
||||
if (method == null)
|
||||
{
|
||||
foreach (var candidateMethod in typeof(FastBufferWriter).GetMethods())
|
||||
{
|
||||
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
|
||||
{
|
||||
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!candidateMethod.GetParameters()[0].ParameterType.IsArray)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
method = candidateMethod.MakeGenericMethod(typeof(T));
|
||||
break;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert.NotNull(method);
|
||||
|
||||
object[] args = new object[method.GetParameters().Length];
|
||||
args[0] = value;
|
||||
for (var i = 1; i < args.Length; ++i)
|
||||
{
|
||||
args[i] = method.GetParameters()[i].DefaultValue;
|
||||
}
|
||||
method.Invoke(writer, args);
|
||||
}
|
||||
|
||||
|
||||
protected override unsafe void RunTypeTest<T>(T valueToTest)
|
||||
{
|
||||
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
|
||||
@@ -82,7 +169,7 @@ namespace Unity.Netcode.EditorTests
|
||||
|
||||
var failMessage = $"RunTypeTest failed with type {typeof(T)} and value {valueToTest}";
|
||||
|
||||
writer.WriteValue(valueToTest);
|
||||
RunMethod(nameof(FastBufferWriter.WriteValue), writer, valueToTest);
|
||||
|
||||
CommonChecks(writer, valueToTest, writeSize, failMessage);
|
||||
}
|
||||
@@ -98,7 +185,7 @@ namespace Unity.Netcode.EditorTests
|
||||
|
||||
var failMessage = $"RunTypeTest failed with type {typeof(T)} and value {valueToTest}";
|
||||
|
||||
writer.WriteValueSafe(valueToTest);
|
||||
RunMethod(nameof(FastBufferWriter.WriteValueSafe), writer, valueToTest);
|
||||
|
||||
CommonChecks(writer, valueToTest, writeSize, failMessage);
|
||||
}
|
||||
@@ -129,7 +216,7 @@ namespace Unity.Netcode.EditorTests
|
||||
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
|
||||
Assert.IsTrue(writer.TryBeginWrite(writeSize + 2), "Writer denied write permission");
|
||||
|
||||
writer.WriteValue(valueToTest);
|
||||
RunMethod(nameof(FastBufferWriter.WriteValue), writer, valueToTest);
|
||||
VerifyPositionAndLength(writer, writeSize);
|
||||
|
||||
WriteCheckBytes(writer, writeSize);
|
||||
@@ -150,7 +237,7 @@ namespace Unity.Netcode.EditorTests
|
||||
|
||||
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
|
||||
|
||||
writer.WriteValueSafe(valueToTest);
|
||||
RunMethod(nameof(FastBufferWriter.WriteValueSafe), writer, valueToTest);
|
||||
VerifyPositionAndLength(writer, writeSize);
|
||||
|
||||
WriteCheckBytes(writer, writeSize);
|
||||
|
||||
49
Tests/Editor/Transports/UNetTransportTests.cs
Normal file
49
Tests/Editor/Transports/UNetTransportTests.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
#if UNITY_UNET_PRESENT
|
||||
#pragma warning disable 618 // disable is obsolete
|
||||
using NUnit.Framework;
|
||||
using Unity.Netcode.Transports.UNET;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Unity.Netcode.EditorTests
|
||||
{
|
||||
public class UNetTransportTests
|
||||
{
|
||||
[Test]
|
||||
public void StartServerReturnsFalseOnFailure()
|
||||
{
|
||||
UNetTransport unet1 = null;
|
||||
UNetTransport unet2 = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Arrange
|
||||
|
||||
// We're expecting an error from UNET, but don't care to validate the specific message
|
||||
LogAssert.ignoreFailingMessages = true;
|
||||
|
||||
var go = new GameObject();
|
||||
unet1 = go.AddComponent<UNetTransport>();
|
||||
unet1.ServerListenPort = 1;
|
||||
unet1.Initialize();
|
||||
unet1.StartServer();
|
||||
unet2 = go.AddComponent<UNetTransport>();
|
||||
unet2.ServerListenPort = 1;
|
||||
unet2.Initialize();
|
||||
|
||||
// Act
|
||||
var result = unet2.StartServer();
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(result, "UNET fails to initialize against port already in use");
|
||||
}
|
||||
finally
|
||||
{
|
||||
unet1?.Shutdown();
|
||||
unet2?.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore 618
|
||||
#endif
|
||||
11
Tests/Editor/Transports/UNetTransportTests.cs.meta
Normal file
11
Tests/Editor/Transports/UNetTransportTests.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e328ef8f7c9b46538253a1b39dc8a97
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -24,6 +24,11 @@
|
||||
"name": "com.unity.multiplayer.tools",
|
||||
"expression": "",
|
||||
"define": "MULTIPLAYER_TOOLS"
|
||||
},
|
||||
{
|
||||
"name": "Unity",
|
||||
"expression": "(0,2022.2.0a5)",
|
||||
"define": "UNITY_UNET_PRESENT"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -3,11 +3,7 @@ using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using Unity.Netcode.TestHelpers.Runtime;
|
||||
#if UNITY_UNET_PRESENT
|
||||
using Unity.Netcode.Transports.UNET;
|
||||
#else
|
||||
using Unity.Netcode.Transports.UTP;
|
||||
#endif
|
||||
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
@@ -26,15 +22,13 @@ namespace Unity.Netcode.RuntimeTests
|
||||
m_NetworkManagerGameObject = new GameObject();
|
||||
m_ClientNetworkManager = m_NetworkManagerGameObject.AddComponent<NetworkManager>();
|
||||
m_ClientNetworkManager.NetworkConfig = new NetworkConfig();
|
||||
#if UNITY_UNET_PRESENT
|
||||
m_TimeoutHelper = new TimeoutHelper(30);
|
||||
m_ClientNetworkManager.NetworkConfig.NetworkTransport = m_NetworkManagerGameObject.AddComponent<UNetTransport>();
|
||||
#else
|
||||
// Default is 1000ms per connection attempt and 60 connection attempts (60s)
|
||||
// Currently there is no easy way to set these values other than in-editor
|
||||
m_TimeoutHelper = new TimeoutHelper(70);
|
||||
m_ClientNetworkManager.NetworkConfig.NetworkTransport = m_NetworkManagerGameObject.AddComponent<UnityTransport>();
|
||||
#endif
|
||||
var unityTransport = m_NetworkManagerGameObject.AddComponent<UnityTransport>();
|
||||
unityTransport.ConnectTimeoutMS = 1000;
|
||||
unityTransport.MaxConnectAttempts = 1;
|
||||
m_TimeoutHelper = new TimeoutHelper(2);
|
||||
m_ClientNetworkManager.NetworkConfig.NetworkTransport = unityTransport;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
@@ -46,10 +40,9 @@ namespace Unity.Netcode.RuntimeTests
|
||||
// Only start the client (so it will timeout)
|
||||
m_ClientNetworkManager.StartClient();
|
||||
|
||||
#if !UNITY_UNET_PRESENT
|
||||
// Unity Transport throws an error when it times out
|
||||
LogAssert.Expect(LogType.Error, "Failed to connect to server.");
|
||||
#endif
|
||||
|
||||
yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(() => m_WasDisconnected, m_TimeoutHelper);
|
||||
Assert.False(m_TimeoutHelper.TimedOut, "Timed out waiting for client to timeout waiting to connect!");
|
||||
|
||||
|
||||
1225
Tests/Runtime/DeferredMessagingTests.cs
Normal file
1225
Tests/Runtime/DeferredMessagingTests.cs
Normal file
File diff suppressed because it is too large
Load Diff
3
Tests/Runtime/DeferredMessagingTests.cs.meta
Normal file
3
Tests/Runtime/DeferredMessagingTests.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3d771dc2a334464ad96e8c66ac776cc
|
||||
timeCreated: 1650295945
|
||||
@@ -9,6 +9,8 @@ namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
public class DisconnectTests
|
||||
{
|
||||
|
||||
private bool m_ClientDisconnected;
|
||||
[UnityTest]
|
||||
public IEnumerator RemoteDisconnectPlayerObjectCleanup()
|
||||
{
|
||||
@@ -38,11 +40,14 @@ namespace Unity.Netcode.RuntimeTests
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForClientConnectedToServer(server);
|
||||
|
||||
// disconnect the remote client
|
||||
m_ClientDisconnected = false;
|
||||
server.DisconnectClient(clients[0].LocalClientId);
|
||||
clients[0].OnClientDisconnectCallback += OnClientDisconnectCallback;
|
||||
var timeoutHelper = new TimeoutHelper();
|
||||
yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(() => m_ClientDisconnected, timeoutHelper);
|
||||
|
||||
// wait 1 frame because destroys are delayed
|
||||
var nextFrameNumber = Time.frameCount + 1;
|
||||
yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber);
|
||||
// We need to do this to remove other associated client properties/values from NetcodeIntegrationTestHelpers
|
||||
NetcodeIntegrationTestHelpers.StopOneClient(clients[0]);
|
||||
|
||||
// ensure the object was destroyed
|
||||
Assert.False(server.SpawnManager.SpawnedObjects.Any(x => x.Value.IsPlayerObject && x.Value.OwnerClientId == clients[0].LocalClientId));
|
||||
@@ -50,5 +55,10 @@ namespace Unity.Netcode.RuntimeTests
|
||||
// cleanup
|
||||
NetcodeIntegrationTestHelpers.Destroy();
|
||||
}
|
||||
|
||||
private void OnClientDisconnectCallback(ulong obj)
|
||||
{
|
||||
m_ClientDisconnected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
public IEnumerator NamedMessageIsReceivedOnClientWithContent()
|
||||
{
|
||||
var messageName = Guid.NewGuid().ToString();
|
||||
var messageContent = Guid.NewGuid();
|
||||
var messageContent = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
var writer = new FastBufferWriter(1300, Allocator.Temp);
|
||||
using (writer)
|
||||
{
|
||||
@@ -39,7 +39,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
|
||||
ulong receivedMessageSender = 0;
|
||||
var receivedMessageContent = new Guid();
|
||||
var receivedMessageContent = new ForceNetworkSerializeByMemcpy<Guid>(new Guid());
|
||||
FirstClient.CustomMessagingManager.RegisterNamedMessageHandler(
|
||||
messageName,
|
||||
(ulong sender, FastBufferReader reader) =>
|
||||
@@ -51,7 +51,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
|
||||
Assert.AreEqual(messageContent, receivedMessageContent);
|
||||
Assert.AreEqual(messageContent.Value, receivedMessageContent.Value);
|
||||
Assert.AreEqual(m_ServerNetworkManager.LocalClientId, receivedMessageSender);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
public IEnumerator NamedMessageIsReceivedOnMultipleClientsWithContent()
|
||||
{
|
||||
var messageName = Guid.NewGuid().ToString();
|
||||
var messageContent = Guid.NewGuid();
|
||||
var messageContent = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
var writer = new FastBufferWriter(1300, Allocator.Temp);
|
||||
using (writer)
|
||||
{
|
||||
@@ -71,7 +71,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
|
||||
ulong firstReceivedMessageSender = 0;
|
||||
var firstReceivedMessageContent = new Guid();
|
||||
var firstReceivedMessageContent = new ForceNetworkSerializeByMemcpy<Guid>(new Guid());
|
||||
FirstClient.CustomMessagingManager.RegisterNamedMessageHandler(
|
||||
messageName,
|
||||
(ulong sender, FastBufferReader reader) =>
|
||||
@@ -82,7 +82,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
});
|
||||
|
||||
ulong secondReceivedMessageSender = 0;
|
||||
var secondReceivedMessageContent = new Guid();
|
||||
var secondReceivedMessageContent = new ForceNetworkSerializeByMemcpy<Guid>(new Guid());
|
||||
SecondClient.CustomMessagingManager.RegisterNamedMessageHandler(
|
||||
messageName,
|
||||
(ulong sender, FastBufferReader reader) =>
|
||||
@@ -94,10 +94,10 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
|
||||
Assert.AreEqual(messageContent, firstReceivedMessageContent);
|
||||
Assert.AreEqual(messageContent.Value, firstReceivedMessageContent.Value);
|
||||
Assert.AreEqual(m_ServerNetworkManager.LocalClientId, firstReceivedMessageSender);
|
||||
|
||||
Assert.AreEqual(messageContent, secondReceivedMessageContent);
|
||||
Assert.AreEqual(messageContent.Value, secondReceivedMessageContent.Value);
|
||||
Assert.AreEqual(m_ServerNetworkManager.LocalClientId, secondReceivedMessageSender);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
public IEnumerator WhenSendingNamedMessageToAll_AllClientsReceiveIt()
|
||||
{
|
||||
var messageName = Guid.NewGuid().ToString();
|
||||
var messageContent = Guid.NewGuid();
|
||||
var messageContent = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
var writer = new FastBufferWriter(1300, Allocator.Temp);
|
||||
using (writer)
|
||||
{
|
||||
@@ -114,7 +114,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
|
||||
ulong firstReceivedMessageSender = 0;
|
||||
var firstReceivedMessageContent = new Guid();
|
||||
var firstReceivedMessageContent = new ForceNetworkSerializeByMemcpy<Guid>(new Guid());
|
||||
FirstClient.CustomMessagingManager.RegisterNamedMessageHandler(
|
||||
messageName,
|
||||
(ulong sender, FastBufferReader reader) =>
|
||||
@@ -125,7 +125,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
});
|
||||
|
||||
ulong secondReceivedMessageSender = 0;
|
||||
var secondReceivedMessageContent = new Guid();
|
||||
var secondReceivedMessageContent = new ForceNetworkSerializeByMemcpy<Guid>(new Guid());
|
||||
SecondClient.CustomMessagingManager.RegisterNamedMessageHandler(
|
||||
messageName,
|
||||
(ulong sender, FastBufferReader reader) =>
|
||||
@@ -137,10 +137,10 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
|
||||
Assert.AreEqual(messageContent, firstReceivedMessageContent);
|
||||
Assert.AreEqual(messageContent.Value, firstReceivedMessageContent.Value);
|
||||
Assert.AreEqual(m_ServerNetworkManager.LocalClientId, firstReceivedMessageSender);
|
||||
|
||||
Assert.AreEqual(messageContent, secondReceivedMessageContent);
|
||||
Assert.AreEqual(messageContent.Value, secondReceivedMessageContent.Value);
|
||||
Assert.AreEqual(m_ServerNetworkManager.LocalClientId, secondReceivedMessageSender);
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
public void WhenSendingNamedMessageToNullClientList_ArgumentNullExceptionIsThrown()
|
||||
{
|
||||
var messageName = Guid.NewGuid().ToString();
|
||||
var messageContent = Guid.NewGuid();
|
||||
var messageContent = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
var writer = new FastBufferWriter(1300, Allocator.Temp);
|
||||
using (writer)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
[UnityTest]
|
||||
public IEnumerator UnnamedMessageIsReceivedOnClientWithContent()
|
||||
{
|
||||
var messageContent = Guid.NewGuid();
|
||||
var messageContent = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
var writer = new FastBufferWriter(1300, Allocator.Temp);
|
||||
using (writer)
|
||||
{
|
||||
@@ -30,7 +30,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
|
||||
ulong receivedMessageSender = 0;
|
||||
var receivedMessageContent = new Guid();
|
||||
var receivedMessageContent = new ForceNetworkSerializeByMemcpy<Guid>(new Guid());
|
||||
FirstClient.CustomMessagingManager.OnUnnamedMessage +=
|
||||
(ulong sender, FastBufferReader reader) =>
|
||||
{
|
||||
@@ -41,14 +41,14 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
|
||||
Assert.AreEqual(messageContent, receivedMessageContent);
|
||||
Assert.AreEqual(messageContent.Value, receivedMessageContent.Value);
|
||||
Assert.AreEqual(m_ServerNetworkManager.LocalClientId, receivedMessageSender);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator UnnamedMessageIsReceivedOnMultipleClientsWithContent()
|
||||
{
|
||||
var messageContent = Guid.NewGuid();
|
||||
var messageContent = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
var writer = new FastBufferWriter(1300, Allocator.Temp);
|
||||
using (writer)
|
||||
{
|
||||
@@ -59,7 +59,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
|
||||
ulong firstReceivedMessageSender = 0;
|
||||
var firstReceivedMessageContent = new Guid();
|
||||
var firstReceivedMessageContent = new ForceNetworkSerializeByMemcpy<Guid>(new Guid());
|
||||
FirstClient.CustomMessagingManager.OnUnnamedMessage +=
|
||||
(ulong sender, FastBufferReader reader) =>
|
||||
{
|
||||
@@ -69,7 +69,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
};
|
||||
|
||||
ulong secondReceivedMessageSender = 0;
|
||||
var secondReceivedMessageContent = new Guid();
|
||||
var secondReceivedMessageContent = new ForceNetworkSerializeByMemcpy<Guid>(new Guid());
|
||||
SecondClient.CustomMessagingManager.OnUnnamedMessage +=
|
||||
(ulong sender, FastBufferReader reader) =>
|
||||
{
|
||||
@@ -80,17 +80,17 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
|
||||
Assert.AreEqual(messageContent, firstReceivedMessageContent);
|
||||
Assert.AreEqual(messageContent.Value, firstReceivedMessageContent.Value);
|
||||
Assert.AreEqual(m_ServerNetworkManager.LocalClientId, firstReceivedMessageSender);
|
||||
|
||||
Assert.AreEqual(messageContent, secondReceivedMessageContent);
|
||||
Assert.AreEqual(messageContent.Value, secondReceivedMessageContent.Value);
|
||||
Assert.AreEqual(m_ServerNetworkManager.LocalClientId, secondReceivedMessageSender);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WhenSendingUnnamedMessageToAll_AllClientsReceiveIt()
|
||||
{
|
||||
var messageContent = Guid.NewGuid();
|
||||
var messageContent = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
var writer = new FastBufferWriter(1300, Allocator.Temp);
|
||||
using (writer)
|
||||
{
|
||||
@@ -99,7 +99,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
|
||||
ulong firstReceivedMessageSender = 0;
|
||||
var firstReceivedMessageContent = new Guid();
|
||||
var firstReceivedMessageContent = new ForceNetworkSerializeByMemcpy<Guid>(new Guid());
|
||||
FirstClient.CustomMessagingManager.OnUnnamedMessage +=
|
||||
(ulong sender, FastBufferReader reader) =>
|
||||
{
|
||||
@@ -109,7 +109,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
};
|
||||
|
||||
ulong secondReceivedMessageSender = 0;
|
||||
var secondReceivedMessageContent = new Guid();
|
||||
var secondReceivedMessageContent = new ForceNetworkSerializeByMemcpy<Guid>(new Guid());
|
||||
SecondClient.CustomMessagingManager.OnUnnamedMessage +=
|
||||
(ulong sender, FastBufferReader reader) =>
|
||||
{
|
||||
@@ -120,17 +120,17 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
|
||||
Assert.AreEqual(messageContent, firstReceivedMessageContent);
|
||||
Assert.AreEqual(messageContent.Value, firstReceivedMessageContent.Value);
|
||||
Assert.AreEqual(m_ServerNetworkManager.LocalClientId, firstReceivedMessageSender);
|
||||
|
||||
Assert.AreEqual(messageContent, secondReceivedMessageContent);
|
||||
Assert.AreEqual(messageContent.Value, secondReceivedMessageContent.Value);
|
||||
Assert.AreEqual(m_ServerNetworkManager.LocalClientId, secondReceivedMessageSender);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenSendingNamedMessageToNullClientList_ArgumentNullExceptionIsThrown()
|
||||
{
|
||||
var messageContent = Guid.NewGuid();
|
||||
var messageContent = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
var writer = new FastBufferWriter(1300, Allocator.Temp);
|
||||
using (writer)
|
||||
{
|
||||
|
||||
@@ -27,12 +27,12 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
{
|
||||
var waitForMetricValues = new WaitForEventMetricValues<NetworkMessageEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.NetworkMessageSent);
|
||||
|
||||
var messageName = Guid.NewGuid();
|
||||
var messageName = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
using (var writer = new FastBufferWriter(1300, Allocator.Temp))
|
||||
{
|
||||
writer.WriteValueSafe(messageName);
|
||||
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.ToString(), FirstClient.LocalClientId, writer);
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), FirstClient.LocalClientId, writer);
|
||||
}
|
||||
|
||||
yield return waitForMetricValues.WaitForMetricsReceived();
|
||||
@@ -47,12 +47,12 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
public IEnumerator TrackNetworkMessageSentMetricToMultipleClients()
|
||||
{
|
||||
var waitForMetricValues = new WaitForEventMetricValues<NetworkMessageEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.NetworkMessageSent);
|
||||
var messageName = Guid.NewGuid();
|
||||
var messageName = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
using (var writer = new FastBufferWriter(1300, Allocator.Temp))
|
||||
{
|
||||
writer.WriteValueSafe(messageName);
|
||||
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.ToString(), new List<ulong> { FirstClient.LocalClientId, SecondClient.LocalClientId }, writer);
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), new List<ulong> { FirstClient.LocalClientId, SecondClient.LocalClientId }, writer);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,10 +65,10 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
[UnityTest]
|
||||
public IEnumerator TrackNetworkMessageReceivedMetric()
|
||||
{
|
||||
var messageName = Guid.NewGuid();
|
||||
var messageName = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
|
||||
LogAssert.Expect(LogType.Log, $"Received from {Server.LocalClientId}");
|
||||
FirstClient.CustomMessagingManager.RegisterNamedMessageHandler(messageName.ToString(), (ulong sender, FastBufferReader payload) =>
|
||||
FirstClient.CustomMessagingManager.RegisterNamedMessageHandler(messageName.Value.ToString(), (ulong sender, FastBufferReader payload) =>
|
||||
{
|
||||
Debug.Log($"Received from {sender}");
|
||||
});
|
||||
@@ -79,7 +79,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
{
|
||||
writer.WriteValueSafe(messageName);
|
||||
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.ToString(), FirstClient.LocalClientId, writer);
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), FirstClient.LocalClientId, writer);
|
||||
}
|
||||
|
||||
yield return waitForMetricValues.WaitForMetricsReceived();
|
||||
@@ -94,12 +94,12 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
{
|
||||
var waitForMetricValues = new WaitForEventMetricValues<NamedMessageEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.NamedMessageSent);
|
||||
|
||||
var messageName = Guid.NewGuid();
|
||||
var messageName = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
using (var writer = new FastBufferWriter(1300, Allocator.Temp))
|
||||
{
|
||||
writer.WriteValueSafe(messageName);
|
||||
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.ToString(), FirstClient.LocalClientId, writer);
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), FirstClient.LocalClientId, writer);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
Assert.AreEqual(1, namedMessageSentMetricValues.Count);
|
||||
|
||||
var namedMessageSent = namedMessageSentMetricValues.First();
|
||||
Assert.AreEqual(messageName.ToString(), namedMessageSent.Name);
|
||||
Assert.AreEqual(messageName.Value.ToString(), namedMessageSent.Name);
|
||||
Assert.AreEqual(FirstClient.LocalClientId, namedMessageSent.Connection.Id);
|
||||
Assert.AreEqual(FastBufferWriter.GetWriteSize(messageName) + k_NamedMessageOverhead, namedMessageSent.BytesCount);
|
||||
}
|
||||
@@ -118,12 +118,12 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
public IEnumerator TrackNamedMessageSentMetricToMultipleClients()
|
||||
{
|
||||
var waitForMetricValues = new WaitForEventMetricValues<NamedMessageEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.NamedMessageSent);
|
||||
var messageName = Guid.NewGuid();
|
||||
var messageName = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
using (var writer = new FastBufferWriter(1300, Allocator.Temp))
|
||||
{
|
||||
writer.WriteValueSafe(messageName);
|
||||
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.ToString(), new List<ulong> { FirstClient.LocalClientId, SecondClient.LocalClientId }, writer);
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), new List<ulong> { FirstClient.LocalClientId, SecondClient.LocalClientId }, writer);
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
|
||||
var namedMessageSentMetricValues = waitForMetricValues.AssertMetricValuesHaveBeenFound();
|
||||
Assert.AreEqual(2, namedMessageSentMetricValues.Count);
|
||||
Assert.That(namedMessageSentMetricValues.Select(x => x.Name), Has.All.EqualTo(messageName.ToString()));
|
||||
Assert.That(namedMessageSentMetricValues.Select(x => x.Name), Has.All.EqualTo(messageName.Value.ToString()));
|
||||
Assert.That(namedMessageSentMetricValues.Select(x => x.BytesCount), Has.All.EqualTo(FastBufferWriter.GetWriteSize(messageName) + k_NamedMessageOverhead));
|
||||
}
|
||||
|
||||
@@ -139,12 +139,12 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
public IEnumerator TrackNamedMessageSentMetricToSelf()
|
||||
{
|
||||
var waitForMetricValues = new WaitForEventMetricValues<NamedMessageEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.NamedMessageSent);
|
||||
var messageName = Guid.NewGuid();
|
||||
var messageName = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
using (var writer = new FastBufferWriter(1300, Allocator.Temp))
|
||||
{
|
||||
writer.WriteValueSafe(messageName);
|
||||
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.ToString(), Server.LocalClientId, writer);
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), Server.LocalClientId, writer);
|
||||
}
|
||||
|
||||
yield return waitForMetricValues.WaitForMetricsReceived();
|
||||
@@ -157,10 +157,10 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
{
|
||||
var waitForMetricValues = new WaitForEventMetricValues<NamedMessageEvent>(FirstClientMetrics.Dispatcher, NetworkMetricTypes.NamedMessageReceived);
|
||||
|
||||
var messageName = Guid.NewGuid();
|
||||
var messageName = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
|
||||
LogAssert.Expect(LogType.Log, $"Received from {Server.LocalClientId}");
|
||||
FirstClient.CustomMessagingManager.RegisterNamedMessageHandler(messageName.ToString(), (ulong sender, FastBufferReader payload) =>
|
||||
FirstClient.CustomMessagingManager.RegisterNamedMessageHandler(messageName.Value.ToString(), (ulong sender, FastBufferReader payload) =>
|
||||
{
|
||||
Debug.Log($"Received from {sender}");
|
||||
});
|
||||
@@ -169,7 +169,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
{
|
||||
writer.WriteValueSafe(messageName);
|
||||
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.ToString(), FirstClient.LocalClientId, writer);
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), FirstClient.LocalClientId, writer);
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
Assert.AreEqual(1, namedMessageReceivedValues.Count);
|
||||
|
||||
var namedMessageReceived = namedMessageReceivedValues.First();
|
||||
Assert.AreEqual(messageName.ToString(), namedMessageReceived.Name);
|
||||
Assert.AreEqual(messageName.Value.ToString(), namedMessageReceived.Name);
|
||||
Assert.AreEqual(Server.LocalClientId, namedMessageReceived.Connection.Id);
|
||||
Assert.AreEqual(FastBufferWriter.GetWriteSize(messageName) + k_NamedMessageOverhead, namedMessageReceived.BytesCount);
|
||||
}
|
||||
@@ -187,7 +187,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
[UnityTest]
|
||||
public IEnumerator TrackUnnamedMessageSentMetric()
|
||||
{
|
||||
var message = Guid.NewGuid();
|
||||
var message = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
using (var writer = new FastBufferWriter(1300, Allocator.Temp))
|
||||
{
|
||||
writer.WriteValueSafe(message);
|
||||
@@ -211,7 +211,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
[UnityTest]
|
||||
public IEnumerator TrackUnnamedMessageSentMetricToMultipleClients()
|
||||
{
|
||||
var message = Guid.NewGuid();
|
||||
var message = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
var waitForMetricValues = new WaitForEventMetricValues<UnnamedMessageEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.UnnamedMessageSent);
|
||||
using (var writer = new FastBufferWriter(1300, Allocator.Temp))
|
||||
{
|
||||
@@ -236,7 +236,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
public IEnumerator TrackUnnamedMessageSentMetricToSelf()
|
||||
{
|
||||
var waitForMetricValues = new WaitForEventMetricValues<UnnamedMessageEvent>(ServerMetrics.Dispatcher, NetworkMetricTypes.UnnamedMessageSent);
|
||||
var messageName = Guid.NewGuid();
|
||||
var messageName = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
using (var writer = new FastBufferWriter(1300, Allocator.Temp))
|
||||
{
|
||||
writer.WriteValueSafe(messageName);
|
||||
@@ -252,7 +252,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
[UnityTest]
|
||||
public IEnumerator TrackUnnamedMessageReceivedMetric()
|
||||
{
|
||||
var message = Guid.NewGuid();
|
||||
var message = new ForceNetworkSerializeByMemcpy<Guid>(Guid.NewGuid());
|
||||
var waitForMetricValues = new WaitForEventMetricValues<UnnamedMessageEvent>(FirstClientMetrics.Dispatcher, NetworkMetricTypes.UnnamedMessageReceived);
|
||||
using (var writer = new FastBufferWriter(1300, Allocator.Temp))
|
||||
{
|
||||
|
||||
@@ -24,11 +24,6 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
: base(HostOrServer.Server)
|
||||
{}
|
||||
|
||||
protected override void OnOneTimeSetup()
|
||||
{
|
||||
m_NetworkTransport = NetcodeIntegrationTestHelpers.InstanceTransport.UTP;
|
||||
}
|
||||
|
||||
protected override void OnServerAndClientsCreated()
|
||||
{
|
||||
var clientTransport = (UnityTransport)m_ClientNetworkManagers[0].NetworkConfig.NetworkTransport;
|
||||
|
||||
@@ -12,13 +12,6 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
{
|
||||
internal class PacketMetricsTests : SingleClientMetricTestBase
|
||||
{
|
||||
|
||||
protected override void OnOneTimeSetup()
|
||||
{
|
||||
m_NetworkTransport = NetcodeIntegrationTestHelpers.InstanceTransport.UTP;
|
||||
base.OnOneTimeSetup();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TrackPacketSentMetric()
|
||||
{
|
||||
|
||||
@@ -40,15 +40,6 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
m_ClientCount = numberOfClients == ClientCount.OneClient ? 1 : 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Note: We are using the OnOneTimeSetup to select the transport to use for
|
||||
/// this test set.
|
||||
/// </summary>
|
||||
protected override void OnOneTimeSetup()
|
||||
{
|
||||
m_NetworkTransport = NetcodeIntegrationTestHelpers.InstanceTransport.UTP;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TrackRttMetricServerToClient()
|
||||
{
|
||||
|
||||
@@ -16,6 +16,12 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
private static readonly int k_ServerLogSentMessageOverhead = 2 + k_MessageHeaderSize;
|
||||
private static readonly int k_ServerLogReceivedMessageOverhead = 2;
|
||||
|
||||
protected override IEnumerator OnSetup()
|
||||
{
|
||||
m_CreateServerFirst = false;
|
||||
return base.OnSetup();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TrackServerLogSentMetric()
|
||||
{
|
||||
|
||||
@@ -20,14 +20,14 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
[UnityTest]
|
||||
public IEnumerator TrackTotalNumberOfBytesSent()
|
||||
{
|
||||
var messageName = Guid.NewGuid();
|
||||
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.ToString(), Client.LocalClientId, writer);
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), Client.LocalClientId, writer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -48,14 +48,14 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
[UnityTest]
|
||||
public IEnumerator TrackTotalNumberOfBytesReceived()
|
||||
{
|
||||
var messageName = Guid.NewGuid();
|
||||
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.ToString(), Client.LocalClientId, writer);
|
||||
Server.CustomMessagingManager.SendNamedMessage(messageName.Value.ToString(), Client.LocalClientId, writer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using UnityEngine;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.TestTools;
|
||||
using Unity.Netcode.TestHelpers.Runtime;
|
||||
using Unity.Netcode.Transports.UTP;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
@@ -14,9 +14,9 @@ namespace Unity.Netcode.RuntimeTests
|
||||
var parent = new GameObject("ParentObject");
|
||||
var networkManagerObject = new GameObject(nameof(CheckNestedNetworkManager));
|
||||
|
||||
var transport = networkManagerObject.AddComponent<SIPTransport>();
|
||||
var unityTransport = networkManagerObject.AddComponent<UnityTransport>();
|
||||
var networkManager = networkManagerObject.AddComponent<NetworkManager>();
|
||||
networkManager.NetworkConfig = new NetworkConfig() { NetworkTransport = transport };
|
||||
networkManager.NetworkConfig = new NetworkConfig() { NetworkTransport = unityTransport };
|
||||
|
||||
// Make our NetworkManager's GameObject nested
|
||||
networkManagerObject.transform.parent = parent.transform;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
// destroy the server player
|
||||
Object.Destroy(serverClientPlayerResult.Result.gameObject);
|
||||
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfType<DestroyObjectMessage>(m_ClientNetworkManagers[0]);
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeHandled<DestroyObjectMessage>(m_ClientNetworkManagers[0]);
|
||||
|
||||
Assert.IsTrue(serverClientPlayerResult.Result == null); // Assert.IsNull doesn't work here
|
||||
Assert.IsTrue(clientClientPlayerResult.Result == null);
|
||||
|
||||
@@ -51,6 +51,8 @@ namespace Unity.Netcode.RuntimeTests
|
||||
yield return s_DefaultWaitForTick;
|
||||
|
||||
// Ensure it's now added to the list
|
||||
yield return WaitForConditionOrTimeOut(() => m_ClientNetworkManagers[0].SpawnManager.GetClientOwnedObjects(m_ClientNetworkManagers[0].LocalClientId).Any(x => x.NetworkObjectId == serverObject.NetworkObjectId));
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for client to gain ownership!");
|
||||
Assert.True(m_ClientNetworkManagers[0].SpawnManager.GetClientOwnedObjects(m_ClientNetworkManagers[0].LocalClientId).Any(x => x.NetworkObjectId == serverObject.NetworkObjectId));
|
||||
Assert.True(m_ServerNetworkManager.SpawnManager.GetClientOwnedObjects(m_ClientNetworkManagers[0].LocalClientId).Any(x => x.NetworkObjectId == serverObject.NetworkObjectId));
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
m_OwnershipObject = SpawnObject(m_OwnershipPrefab, m_ServerNetworkManager);
|
||||
m_OwnershipNetworkObject = m_OwnershipObject.GetComponent<NetworkObject>();
|
||||
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfType<CreateObjectMessage>(m_ClientNetworkManagers[0]);
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeHandled<CreateObjectMessage>(m_ClientNetworkManagers[0]);
|
||||
|
||||
var ownershipNetworkObjectId = m_OwnershipNetworkObject.NetworkObjectId;
|
||||
Assert.That(ownershipNetworkObjectId, Is.GreaterThan(0));
|
||||
@@ -95,11 +95,14 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
Assert.That(m_ServerNetworkManager.ConnectedClients.ContainsKey(m_ClientNetworkManagers[0].LocalClientId));
|
||||
|
||||
serverObject.ChangeOwnership(m_ClientNetworkManagers[0].LocalClientId);
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForTicks(m_ServerNetworkManager, 2);
|
||||
serverObject.ChangeOwnership(clientComponent.NetworkManager.LocalClientId);
|
||||
yield return s_DefaultWaitForTick;
|
||||
|
||||
Assert.That(serverComponent.OnLostOwnershipFired);
|
||||
Assert.That(serverComponent.OwnerClientId, Is.EqualTo(m_ClientNetworkManagers[0].LocalClientId));
|
||||
|
||||
yield return WaitForConditionOrTimeOut(() => clientComponent.OnGainedOwnershipFired);
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for client to gain ownership!");
|
||||
Assert.That(clientComponent.OnGainedOwnershipFired);
|
||||
Assert.That(clientComponent.OwnerClientId, Is.EqualTo(m_ClientNetworkManagers[0].LocalClientId));
|
||||
|
||||
@@ -107,10 +110,13 @@ namespace Unity.Netcode.RuntimeTests
|
||||
clientComponent.ResetFlags();
|
||||
|
||||
serverObject.ChangeOwnership(NetworkManager.ServerClientId);
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForTicks(m_ServerNetworkManager, 2);
|
||||
yield return s_DefaultWaitForTick;
|
||||
|
||||
Assert.That(serverComponent.OnGainedOwnershipFired);
|
||||
Assert.That(serverComponent.OwnerClientId, Is.EqualTo(m_ServerNetworkManager.LocalClientId));
|
||||
|
||||
yield return WaitForConditionOrTimeOut(() => clientComponent.OnLostOwnershipFired);
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for client to lose ownership!");
|
||||
Assert.That(clientComponent.OnLostOwnershipFired);
|
||||
Assert.That(clientComponent.OwnerClientId, Is.EqualTo(m_ServerNetworkManager.LocalClientId));
|
||||
}
|
||||
@@ -151,11 +157,22 @@ namespace Unity.Netcode.RuntimeTests
|
||||
var ownershipNetworkObjectId = m_OwnershipNetworkObject.NetworkObjectId;
|
||||
Assert.That(ownershipNetworkObjectId, Is.GreaterThan(0));
|
||||
Assert.That(m_ServerNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(ownershipNetworkObjectId));
|
||||
foreach (var clientNetworkManager in m_ClientNetworkManagers)
|
||||
|
||||
bool WaitForClientsToSpawnNetworkObject()
|
||||
{
|
||||
Assert.That(clientNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(ownershipNetworkObjectId));
|
||||
foreach (var clientNetworkManager in m_ClientNetworkManagers)
|
||||
{
|
||||
if (!clientNetworkManager.SpawnManager.SpawnedObjects.ContainsKey(ownershipNetworkObjectId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
yield return WaitForConditionOrTimeOut(WaitForClientsToSpawnNetworkObject);
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, "Timed out waiting for all clients to change ownership!");
|
||||
|
||||
// Verifies that removing the ownership when the default (server) is already set does not cause a Key Not Found Exception
|
||||
m_ServerNetworkManager.SpawnManager.RemoveOwnership(m_OwnershipNetworkObject);
|
||||
var serverObject = m_ServerNetworkManager.SpawnManager.SpawnedObjects[ownershipNetworkObjectId];
|
||||
@@ -237,7 +254,10 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
Assert.That(serverComponent.OnGainedOwnershipFired);
|
||||
Assert.That(serverComponent.OwnerClientId, Is.EqualTo(m_ServerNetworkManager.LocalClientId));
|
||||
Assert.That(previousClientComponent.OnLostOwnershipFired);
|
||||
|
||||
yield return WaitForConditionOrTimeOut(() => previousClientComponent.OnLostOwnershipFired);
|
||||
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for {previousClientComponent.name} to lose ownership!");
|
||||
|
||||
// Make sure all client-side versions of the object is once again owned by the server
|
||||
for (int i = 0; i < NumberOfClients; i++)
|
||||
|
||||
@@ -91,6 +91,8 @@ namespace Unity.Netcode.RuntimeTests
|
||||
Assert.AreEqual(clientSideClientId, clientSideClientPlayerObject.OwnerClientId);
|
||||
}
|
||||
|
||||
private bool m_ClientDisconnected;
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TestConnectAndDisconnect()
|
||||
{
|
||||
@@ -120,11 +122,22 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
// test when client disconnects, player object no longer available.
|
||||
var nbConnectedClients = m_ServerNetworkManager.ConnectedClients.Count;
|
||||
m_ClientDisconnected = false;
|
||||
newClientNetworkManager.OnClientDisconnectCallback += ClientNetworkManager_OnClientDisconnectCallback;
|
||||
m_ServerNetworkManager.DisconnectClient(newClientLocalClientId);
|
||||
yield return WaitForConditionOrTimeOut(() => m_ClientDisconnected);
|
||||
Assert.IsFalse(s_GlobalTimeoutHelper.TimedOut, "Timed out waiting for client to disconnect");
|
||||
// Call this to clean up NetcodeIntegrationTestHelpers
|
||||
NetcodeIntegrationTestHelpers.StopOneClient(newClientNetworkManager);
|
||||
yield return WaitForConditionOrTimeOut(() => m_ServerNetworkManager.ConnectedClients.Count == nbConnectedClients - 1);
|
||||
|
||||
Assert.AreEqual(m_ServerNetworkManager.ConnectedClients.Count, nbConnectedClients - 1);
|
||||
serverSideNewClientPlayer = m_ServerNetworkManager.SpawnManager.GetPlayerNetworkObject(newClientLocalClientId);
|
||||
Assert.Null(serverSideNewClientPlayer);
|
||||
}
|
||||
|
||||
private void ClientNetworkManager_OnClientDisconnectCallback(ulong obj)
|
||||
{
|
||||
m_ClientDisconnected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
277
Tests/Runtime/NetworkTransform/NetworkTransformOwnershipTests.cs
Normal file
277
Tests/Runtime/NetworkTransform/NetworkTransformOwnershipTests.cs
Normal file
@@ -0,0 +1,277 @@
|
||||
#if COM_UNITY_MODULES_PHYSICS
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.Netcode.Components;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using Unity.Netcode.TestHelpers.Runtime;
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
public class NetworkTransformOwnershipTests : NetcodeIntegrationTest
|
||||
{
|
||||
protected override int NumberOfClients => 1;
|
||||
|
||||
private GameObject m_ClientNetworkTransformPrefab;
|
||||
private GameObject m_NetworkTransformPrefab;
|
||||
|
||||
protected override void OnServerAndClientsCreated()
|
||||
{
|
||||
VerifyObjectIsSpawnedOnClient.ResetObjectTable();
|
||||
m_ClientNetworkTransformPrefab = CreateNetworkObjectPrefab("OwnerAuthorityTest");
|
||||
var clientNetworkTransform = m_ClientNetworkTransformPrefab.AddComponent<TestClientNetworkTransform>();
|
||||
clientNetworkTransform.Interpolate = false;
|
||||
var rigidBody = m_ClientNetworkTransformPrefab.AddComponent<Rigidbody>();
|
||||
rigidBody.useGravity = false;
|
||||
m_ClientNetworkTransformPrefab.AddComponent<NetworkRigidbody>();
|
||||
m_ClientNetworkTransformPrefab.AddComponent<SphereCollider>();
|
||||
m_ClientNetworkTransformPrefab.AddComponent<VerifyObjectIsSpawnedOnClient>();
|
||||
|
||||
m_NetworkTransformPrefab = CreateNetworkObjectPrefab("ServerAuthorityTest");
|
||||
var networkTransform = m_NetworkTransformPrefab.AddComponent<NetworkTransform>();
|
||||
rigidBody = m_NetworkTransformPrefab.AddComponent<Rigidbody>();
|
||||
rigidBody.useGravity = false;
|
||||
m_NetworkTransformPrefab.AddComponent<NetworkRigidbody>();
|
||||
m_NetworkTransformPrefab.AddComponent<SphereCollider>();
|
||||
m_NetworkTransformPrefab.AddComponent<VerifyObjectIsSpawnedOnClient>();
|
||||
networkTransform.Interpolate = false;
|
||||
|
||||
base.OnServerAndClientsCreated();
|
||||
}
|
||||
|
||||
public enum StartingOwnership
|
||||
{
|
||||
HostStartsAsOwner,
|
||||
ClientStartsAsOwner,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This verifies that when authority is owner authoritative the owner's
|
||||
/// Rigidbody is kinematic and the non-owner's is not.
|
||||
/// This also verifies that we can switch between owners and that only the
|
||||
/// owner can update the transform while non-owners cannot.
|
||||
/// </summary>
|
||||
/// <param name="spawnWithHostOwnership">determines who starts as the owner (true): host | (false): client</param>
|
||||
[UnityTest]
|
||||
public IEnumerator OwnerAuthoritativeTest([Values] StartingOwnership startingOwnership)
|
||||
{
|
||||
// Get the current ownership layout
|
||||
var networkManagerOwner = startingOwnership == StartingOwnership.HostStartsAsOwner ? m_ServerNetworkManager : m_ClientNetworkManagers[0];
|
||||
var networkManagerNonOwner = startingOwnership == StartingOwnership.HostStartsAsOwner ? m_ClientNetworkManagers[0] : m_ServerNetworkManager;
|
||||
|
||||
// Spawn the m_ClientNetworkTransformPrefab and wait for the client-side to spawn the object
|
||||
var serverSideInstance = SpawnObject(m_ClientNetworkTransformPrefab, networkManagerOwner);
|
||||
yield return WaitForConditionOrTimeOut(() => VerifyObjectIsSpawnedOnClient.GetClientsThatSpawnedThisPrefab().Contains(m_ClientNetworkManagers[0].LocalClientId));
|
||||
|
||||
// Get owner relative instances
|
||||
var ownerInstance = VerifyObjectIsSpawnedOnClient.GetClientInstance(networkManagerOwner.LocalClientId);
|
||||
var nonOwnerInstance = VerifyObjectIsSpawnedOnClient.GetClientInstance(networkManagerNonOwner.LocalClientId);
|
||||
Assert.NotNull(ownerInstance);
|
||||
Assert.NotNull(nonOwnerInstance);
|
||||
|
||||
// Make sure the owner is not kinematic and the non-owner(s) are kinematic
|
||||
Assert.True(nonOwnerInstance.GetComponent<Rigidbody>().isKinematic, $"{networkManagerNonOwner.name}'s object instance {nonOwnerInstance.name} is not kinematic when it should be!");
|
||||
Assert.False(ownerInstance.GetComponent<Rigidbody>().isKinematic, $"{networkManagerOwner.name}'s object instance {ownerInstance.name} is kinematic when it should not be!");
|
||||
|
||||
// Owner changes transform values
|
||||
var valueSetByOwner = Vector3.one * 2;
|
||||
ownerInstance.transform.position = valueSetByOwner;
|
||||
ownerInstance.transform.localScale = valueSetByOwner;
|
||||
var rotation = new Quaternion();
|
||||
rotation.eulerAngles = valueSetByOwner;
|
||||
ownerInstance.transform.rotation = rotation;
|
||||
var transformToTest = nonOwnerInstance.transform;
|
||||
yield return WaitForConditionOrTimeOut(() => transformToTest.position == valueSetByOwner && transformToTest.localScale == valueSetByOwner && transformToTest.rotation == rotation);
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for {networkManagerNonOwner.name}'s object instance {nonOwnerInstance.name} to change its transform!\n" +
|
||||
$"Expected Position: {valueSetByOwner} | Current Position: {transformToTest.position}\n" +
|
||||
$"Expected Rotation: {valueSetByOwner} | Current Rotation: {transformToTest.rotation.eulerAngles}\n" +
|
||||
$"Expected Scale: {valueSetByOwner} | Current Scale: {transformToTest.localScale}");
|
||||
|
||||
// Verify non-owners cannot change transform values
|
||||
nonOwnerInstance.transform.position = Vector3.zero;
|
||||
yield return s_DefaultWaitForTick;
|
||||
Assert.True(nonOwnerInstance.transform.position == valueSetByOwner, $"{networkManagerNonOwner.name}'s object instance {nonOwnerInstance.name} was allowed to change its position! Expected: {Vector3.one} Is Currently:{nonOwnerInstance.transform.position}");
|
||||
|
||||
// Change ownership and wait for the non-owner to reflect the change
|
||||
VerifyObjectIsSpawnedOnClient.ResetObjectTable();
|
||||
m_ServerNetworkManager.SpawnManager.ChangeOwnership(serverSideInstance.GetComponent<NetworkObject>(), networkManagerNonOwner.LocalClientId);
|
||||
yield return WaitForConditionOrTimeOut(() => nonOwnerInstance.GetComponent<NetworkObject>().OwnerClientId == networkManagerNonOwner.LocalClientId);
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for {networkManagerNonOwner.name}'s object instance {nonOwnerInstance.name} to change ownership!");
|
||||
|
||||
// Re-assign the ownership references and wait for the non-owner instance to be notified of ownership change
|
||||
networkManagerOwner = startingOwnership == StartingOwnership.HostStartsAsOwner ? m_ClientNetworkManagers[0] : m_ServerNetworkManager;
|
||||
networkManagerNonOwner = startingOwnership == StartingOwnership.HostStartsAsOwner ? m_ServerNetworkManager : m_ClientNetworkManagers[0];
|
||||
ownerInstance = VerifyObjectIsSpawnedOnClient.GetClientInstance(networkManagerOwner.LocalClientId);
|
||||
Assert.NotNull(ownerInstance);
|
||||
yield return WaitForConditionOrTimeOut(() => VerifyObjectIsSpawnedOnClient.GetClientInstance(networkManagerNonOwner.LocalClientId) != null);
|
||||
nonOwnerInstance = VerifyObjectIsSpawnedOnClient.GetClientInstance(networkManagerNonOwner.LocalClientId);
|
||||
Assert.NotNull(nonOwnerInstance);
|
||||
|
||||
// Make sure the owner is not kinematic and the non-owner(s) are kinematic
|
||||
Assert.False(ownerInstance.GetComponent<Rigidbody>().isKinematic, $"{networkManagerOwner.name}'s object instance {ownerInstance.name} is kinematic when it should not be!");
|
||||
Assert.True(nonOwnerInstance.GetComponent<Rigidbody>().isKinematic, $"{networkManagerNonOwner.name}'s object instance {nonOwnerInstance.name} is not kinematic when it should be!");
|
||||
|
||||
// Have the new owner change transform values and wait for those values to be applied on the non-owner side.
|
||||
valueSetByOwner = Vector3.one * 50;
|
||||
ownerInstance.transform.position = valueSetByOwner;
|
||||
ownerInstance.transform.localScale = valueSetByOwner;
|
||||
rotation.eulerAngles = valueSetByOwner;
|
||||
ownerInstance.transform.rotation = rotation;
|
||||
transformToTest = nonOwnerInstance.transform;
|
||||
yield return WaitForConditionOrTimeOut(() => transformToTest.position == valueSetByOwner && transformToTest.localScale == valueSetByOwner && transformToTest.rotation == rotation);
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for {networkManagerNonOwner.name}'s object instance {nonOwnerInstance.name} to change its transform!\n" +
|
||||
$"Expected Position: {valueSetByOwner} | Current Position: {transformToTest.position}\n" +
|
||||
$"Expected Rotation: {valueSetByOwner} | Current Rotation: {transformToTest.rotation.eulerAngles}\n" +
|
||||
$"Expected Scale: {valueSetByOwner} | Current Scale: {transformToTest.localScale}");
|
||||
|
||||
// The last check is to verify non-owners cannot change transform values after ownership has changed
|
||||
nonOwnerInstance.transform.position = Vector3.zero;
|
||||
yield return s_DefaultWaitForTick;
|
||||
Assert.True(nonOwnerInstance.transform.position == valueSetByOwner, $"{networkManagerNonOwner.name}'s object instance {nonOwnerInstance.name} was allowed to change its position! Expected: {Vector3.one} Is Currently:{nonOwnerInstance.transform.position}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This verifies that when authority is server authoritative the
|
||||
/// client's Rigidbody is kinematic and the server is not.
|
||||
/// This also verifies only the server can apply updates to the
|
||||
/// transform while the clients cannot.
|
||||
/// </summary>
|
||||
[UnityTest]
|
||||
public IEnumerator ServerAuthoritativeTest()
|
||||
{
|
||||
// Spawn the m_NetworkTransformPrefab and wait for the client-side to spawn the object
|
||||
var serverSideInstance = SpawnObject(m_NetworkTransformPrefab, m_ServerNetworkManager);
|
||||
yield return WaitForConditionOrTimeOut(() => VerifyObjectIsSpawnedOnClient.GetClientsThatSpawnedThisPrefab().Contains(m_ClientNetworkManagers[0].LocalClientId));
|
||||
|
||||
var ownerInstance = VerifyObjectIsSpawnedOnClient.GetClientInstance(m_ServerNetworkManager.LocalClientId);
|
||||
var nonOwnerInstance = VerifyObjectIsSpawnedOnClient.GetClientInstance(m_ClientNetworkManagers[0].LocalClientId);
|
||||
|
||||
// Make sure the owner is not kinematic and the non-owner(s) are kinematic
|
||||
Assert.False(ownerInstance.GetComponent<Rigidbody>().isKinematic, $"{m_ServerNetworkManager.name}'s object instance {ownerInstance.name} is kinematic when it should not be!");
|
||||
Assert.True(nonOwnerInstance.GetComponent<Rigidbody>().isKinematic, $"{m_ClientNetworkManagers[0].name}'s object instance {nonOwnerInstance.name} is not kinematic when it should be!");
|
||||
|
||||
// Server changes transform values
|
||||
var valueSetByOwner = Vector3.one * 2;
|
||||
ownerInstance.transform.position = valueSetByOwner;
|
||||
ownerInstance.transform.localScale = valueSetByOwner;
|
||||
var rotation = new Quaternion();
|
||||
rotation.eulerAngles = valueSetByOwner;
|
||||
ownerInstance.transform.rotation = rotation;
|
||||
var transformToTest = nonOwnerInstance.transform;
|
||||
yield return WaitForConditionOrTimeOut(() => transformToTest.position == valueSetByOwner && transformToTest.localScale == valueSetByOwner && transformToTest.rotation == rotation);
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for {m_ClientNetworkManagers[0].name}'s object instance {nonOwnerInstance.name} to change its transform!\n" +
|
||||
$"Expected Position: {valueSetByOwner} | Current Position: {transformToTest.position}\n" +
|
||||
$"Expected Rotation: {valueSetByOwner} | Current Rotation: {transformToTest.rotation.eulerAngles}\n" +
|
||||
$"Expected Scale: {valueSetByOwner} | Current Scale: {transformToTest.localScale}");
|
||||
|
||||
// The last check is to verify clients cannot change transform values
|
||||
nonOwnerInstance.transform.position = Vector3.zero;
|
||||
yield return s_DefaultWaitForTick;
|
||||
Assert.True(nonOwnerInstance.transform.position == valueSetByOwner, $"{m_ClientNetworkManagers[0].name}'s object instance {nonOwnerInstance.name} was allowed to change its position! Expected: {Vector3.one} Is Currently:{nonOwnerInstance.transform.position}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NetworkTransformOwnershipTests helper behaviour
|
||||
/// </summary>
|
||||
public class VerifyObjectIsSpawnedOnClient : NetworkBehaviour
|
||||
{
|
||||
private static Dictionary<ulong, VerifyObjectIsSpawnedOnClient> s_NetworkManagerRelativeSpawnedObjects = new Dictionary<ulong, VerifyObjectIsSpawnedOnClient>();
|
||||
|
||||
public static void ResetObjectTable()
|
||||
{
|
||||
s_NetworkManagerRelativeSpawnedObjects.Clear();
|
||||
}
|
||||
|
||||
public override void OnGainedOwnership()
|
||||
{
|
||||
if (!s_NetworkManagerRelativeSpawnedObjects.ContainsKey(NetworkManager.LocalClientId))
|
||||
{
|
||||
s_NetworkManagerRelativeSpawnedObjects.Add(NetworkManager.LocalClientId, this);
|
||||
}
|
||||
base.OnGainedOwnership();
|
||||
}
|
||||
|
||||
public override void OnLostOwnership()
|
||||
{
|
||||
if (!s_NetworkManagerRelativeSpawnedObjects.ContainsKey(NetworkManager.LocalClientId))
|
||||
{
|
||||
s_NetworkManagerRelativeSpawnedObjects.Add(NetworkManager.LocalClientId, this);
|
||||
}
|
||||
base.OnLostOwnership();
|
||||
}
|
||||
|
||||
public static List<ulong> GetClientsThatSpawnedThisPrefab()
|
||||
{
|
||||
return s_NetworkManagerRelativeSpawnedObjects.Keys.ToList();
|
||||
}
|
||||
|
||||
public static VerifyObjectIsSpawnedOnClient GetClientInstance(ulong clientId)
|
||||
{
|
||||
if (s_NetworkManagerRelativeSpawnedObjects.ContainsKey(clientId))
|
||||
{
|
||||
return s_NetworkManagerRelativeSpawnedObjects[clientId];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
// This makes sure that the NetworkManager relative NetworkObject instances don't collide with each other
|
||||
// and skew the expected changes to the transforms
|
||||
foreach (var entry in s_NetworkManagerRelativeSpawnedObjects)
|
||||
{
|
||||
Physics.IgnoreCollision(entry.Value.GetComponent<SphereCollider>(), GetComponent<SphereCollider>());
|
||||
}
|
||||
|
||||
if (!s_NetworkManagerRelativeSpawnedObjects.ContainsKey(NetworkManager.LocalClientId))
|
||||
{
|
||||
s_NetworkManagerRelativeSpawnedObjects.Add(NetworkManager.LocalClientId, this);
|
||||
}
|
||||
base.OnNetworkSpawn();
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
if (s_NetworkManagerRelativeSpawnedObjects.ContainsKey(NetworkManager.LocalClientId))
|
||||
{
|
||||
s_NetworkManagerRelativeSpawnedObjects.Remove(NetworkManager.LocalClientId);
|
||||
}
|
||||
base.OnNetworkDespawn();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Until we can better locate the ClientNetworkTransform
|
||||
/// This will have to be used to verify the ownership authority
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class TestClientNetworkTransform : NetworkTransform
|
||||
{
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
base.OnNetworkSpawn();
|
||||
CanCommitToTransform = IsOwner;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
CanCommitToTransform = IsOwner;
|
||||
base.Update();
|
||||
if (NetworkManager.Singleton != null && (NetworkManager.Singleton.IsConnectedClient || NetworkManager.Singleton.IsListening))
|
||||
{
|
||||
if (CanCommitToTransform)
|
||||
{
|
||||
TryCommitTransformToServer(transform, NetworkManager.LocalTime.Time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnIsServerAuthoritatitive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2f8cf0e06334cb4f9f7d4ca3c2d19e3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -22,6 +22,11 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
ReadyToReceivePositionUpdate = true;
|
||||
}
|
||||
|
||||
public (bool isDirty, bool isPositionDirty, bool isRotationDirty, bool isScaleDirty) ApplyState()
|
||||
{
|
||||
return ApplyLocalNetworkState(transform);
|
||||
}
|
||||
}
|
||||
|
||||
// [TestFixture(true, true)]
|
||||
@@ -172,6 +177,80 @@ namespace Unity.Netcode.RuntimeTests
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Validates that rotation checks don't produce false positive
|
||||
/// results when rolling over between 0 and 360 degrees
|
||||
/// </summary>
|
||||
[UnityTest]
|
||||
public IEnumerator TestRotationThresholdDeltaCheck()
|
||||
{
|
||||
// Get the client player's NetworkTransform for both instances
|
||||
var authoritativeNetworkTransform = m_ServerSideClientPlayer.GetComponent<NetworkTransformTestComponent>();
|
||||
var otherSideNetworkTransform = m_ClientSideClientPlayer.GetComponent<NetworkTransformTestComponent>();
|
||||
otherSideNetworkTransform.RotAngleThreshold = authoritativeNetworkTransform.RotAngleThreshold = 5.0f;
|
||||
|
||||
var halfThreshold = authoritativeNetworkTransform.RotAngleThreshold * 0.5001f;
|
||||
var serverRotation = authoritativeNetworkTransform.transform.rotation;
|
||||
var serverEulerRotation = serverRotation.eulerAngles;
|
||||
|
||||
// Verify rotation is not marked dirty when rotated by half of the threshold
|
||||
serverEulerRotation.y += halfThreshold;
|
||||
serverRotation.eulerAngles = serverEulerRotation;
|
||||
authoritativeNetworkTransform.transform.rotation = serverRotation;
|
||||
var results = authoritativeNetworkTransform.ApplyState();
|
||||
Assert.IsFalse(results.isRotationDirty, $"Rotation is dirty when rotation threshold is {authoritativeNetworkTransform.RotAngleThreshold} degrees and only adjusted by {halfThreshold} degrees!");
|
||||
yield return s_DefaultWaitForTick;
|
||||
|
||||
// Verify rotation is marked dirty when rotated by another half threshold value
|
||||
serverEulerRotation.y += halfThreshold;
|
||||
serverRotation.eulerAngles = serverEulerRotation;
|
||||
authoritativeNetworkTransform.transform.rotation = serverRotation;
|
||||
results = authoritativeNetworkTransform.ApplyState();
|
||||
Assert.IsTrue(results.isRotationDirty, $"Rotation was not dirty when rotated by the threshold value: {authoritativeNetworkTransform.RotAngleThreshold} degrees!");
|
||||
yield return s_DefaultWaitForTick;
|
||||
|
||||
//Reset rotation back to zero on all axis
|
||||
serverRotation.eulerAngles = serverEulerRotation = Vector3.zero;
|
||||
authoritativeNetworkTransform.transform.rotation = serverRotation;
|
||||
yield return s_DefaultWaitForTick;
|
||||
|
||||
// Rotate by 360 minus halfThreshold (which is really just negative halfThreshold) and verify rotation is not marked dirty
|
||||
serverEulerRotation.y = 360 - halfThreshold;
|
||||
serverRotation.eulerAngles = serverEulerRotation;
|
||||
authoritativeNetworkTransform.transform.rotation = serverRotation;
|
||||
results = authoritativeNetworkTransform.ApplyState();
|
||||
|
||||
Assert.IsFalse(results.isRotationDirty, $"Rotation is dirty when rotation threshold is {authoritativeNetworkTransform.RotAngleThreshold} degrees and only adjusted by " +
|
||||
$"{Mathf.DeltaAngle(0, serverEulerRotation.y)} degrees!");
|
||||
|
||||
serverEulerRotation.y -= halfThreshold;
|
||||
serverRotation.eulerAngles = serverEulerRotation;
|
||||
authoritativeNetworkTransform.transform.rotation = serverRotation;
|
||||
results = authoritativeNetworkTransform.ApplyState();
|
||||
|
||||
Assert.IsTrue(results.isRotationDirty, $"Rotation was not dirty when rotated by {Mathf.DeltaAngle(0, serverEulerRotation.y)} degrees!");
|
||||
|
||||
//Reset rotation back to zero on all axis
|
||||
serverRotation.eulerAngles = serverEulerRotation = Vector3.zero;
|
||||
authoritativeNetworkTransform.transform.rotation = serverRotation;
|
||||
yield return s_DefaultWaitForTick;
|
||||
|
||||
serverEulerRotation.y -= halfThreshold;
|
||||
serverRotation.eulerAngles = serverEulerRotation;
|
||||
authoritativeNetworkTransform.transform.rotation = serverRotation;
|
||||
results = authoritativeNetworkTransform.ApplyState();
|
||||
Assert.IsFalse(results.isRotationDirty, $"Rotation is dirty when rotation threshold is {authoritativeNetworkTransform.RotAngleThreshold} degrees and only adjusted by " +
|
||||
$"{Mathf.DeltaAngle(0, serverEulerRotation.y)} degrees!");
|
||||
|
||||
serverEulerRotation.y -= halfThreshold;
|
||||
serverRotation.eulerAngles = serverEulerRotation;
|
||||
authoritativeNetworkTransform.transform.rotation = serverRotation;
|
||||
results = authoritativeNetworkTransform.ApplyState();
|
||||
|
||||
Assert.IsTrue(results.isRotationDirty, $"Rotation was not dirty when rotated by {Mathf.DeltaAngle(0, serverEulerRotation.y)} degrees!");
|
||||
}
|
||||
|
||||
/*
|
||||
* ownership change
|
||||
* test teleport with interpolation
|
||||
|
||||
@@ -273,9 +273,9 @@ namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
public readonly NetworkVariable<int> TheScalar = new NetworkVariable<int>();
|
||||
public readonly NetworkList<int> TheList = new NetworkList<int>();
|
||||
public readonly NetworkList<FixedString128Bytes> TheLargeList = new NetworkList<FixedString128Bytes>();
|
||||
public readonly NetworkList<ForceNetworkSerializeByMemcpy<FixedString128Bytes>> TheLargeList = new NetworkList<ForceNetworkSerializeByMemcpy<FixedString128Bytes>>();
|
||||
|
||||
public readonly NetworkVariable<FixedString32Bytes> FixedString32 = new NetworkVariable<FixedString32Bytes>();
|
||||
public readonly NetworkVariable<ForceNetworkSerializeByMemcpy<FixedString32Bytes>> FixedString32 = new NetworkVariable<ForceNetworkSerializeByMemcpy<FixedString32Bytes>>();
|
||||
|
||||
private void ListChanged(NetworkListEvent<int> e)
|
||||
{
|
||||
@@ -306,7 +306,8 @@ namespace Unity.Netcode.RuntimeTests
|
||||
[TestFixture(false)]
|
||||
public class NetworkVariableTests : NetcodeIntegrationTest
|
||||
{
|
||||
private const string k_FixedStringTestValue = "abcdefghijklmnopqrstuvwxyz";
|
||||
private const string k_StringTestValue = "abcdefghijklmnopqrstuvwxyz";
|
||||
private static readonly FixedString32Bytes k_FixedStringTestValue = k_StringTestValue;
|
||||
protected override int NumberOfClients => 2;
|
||||
|
||||
private const uint k_TestUInt = 0x12345678;
|
||||
|
||||
@@ -8,29 +8,16 @@ using Unity.Netcode.TestHelpers.Runtime;
|
||||
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
public class NetworkRigidbodyDynamicTest : NetworkRigidbodyTestBase
|
||||
{
|
||||
public override bool Kinematic => false;
|
||||
}
|
||||
|
||||
public class NetworkRigidbodyKinematicTest : NetworkRigidbodyTestBase
|
||||
{
|
||||
public override bool Kinematic => true;
|
||||
}
|
||||
|
||||
public abstract class NetworkRigidbodyTestBase : NetcodeIntegrationTest
|
||||
public class NetworkRigidbodyTest : NetcodeIntegrationTest
|
||||
{
|
||||
protected override int NumberOfClients => 1;
|
||||
|
||||
public abstract bool Kinematic { get; }
|
||||
|
||||
protected override void OnCreatePlayerPrefab()
|
||||
{
|
||||
m_PlayerPrefab.AddComponent<NetworkTransform>();
|
||||
m_PlayerPrefab.AddComponent<Rigidbody>();
|
||||
m_PlayerPrefab.AddComponent<NetworkRigidbody>();
|
||||
m_PlayerPrefab.GetComponent<Rigidbody>().interpolation = RigidbodyInterpolation.Interpolate;
|
||||
m_PlayerPrefab.GetComponent<Rigidbody>().isKinematic = Kinematic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -55,8 +42,8 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForTicks(m_ServerNetworkManager, 3);
|
||||
|
||||
// server rigidbody has authority and should have a kinematic mode of false
|
||||
Assert.True(serverPlayer.GetComponent<Rigidbody>().isKinematic == Kinematic, "serverPlayer kinematic");
|
||||
// server rigidbody has authority and should not be kinematic
|
||||
Assert.True(serverPlayer.GetComponent<Rigidbody>().isKinematic == false, "serverPlayer kinematic");
|
||||
Assert.AreEqual(RigidbodyInterpolation.Interpolate, serverPlayer.GetComponent<Rigidbody>().interpolation, "server equal interpolate");
|
||||
|
||||
// client rigidbody has no authority and should have a kinematic mode of true
|
||||
@@ -68,7 +55,8 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForTicks(m_ServerNetworkManager, 3);
|
||||
|
||||
Assert.IsTrue(serverPlayer.GetComponent<Rigidbody>().isKinematic == Kinematic, "serverPlayer second kinematic");
|
||||
// When despawned, we should always be kinematic (i.e. don't apply physics when despawned)
|
||||
Assert.IsTrue(serverPlayer.GetComponent<Rigidbody>().isKinematic == true, "serverPlayer second kinematic");
|
||||
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForTicks(m_ServerNetworkManager, 3);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.TestTools;
|
||||
using Unity.Netcode.TestHelpers.Runtime;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
@@ -13,6 +14,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
public class RpcTestNB : NetworkBehaviour
|
||||
{
|
||||
public event Action<ulong, ServerRpcParams> OnServer_Rpc;
|
||||
public event Action<Vector3, Vector3[]> OnTypedServer_Rpc;
|
||||
public event Action OnClient_Rpc;
|
||||
|
||||
[ServerRpc]
|
||||
@@ -26,6 +28,12 @@ namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
OnClient_Rpc();
|
||||
}
|
||||
|
||||
[ServerRpc]
|
||||
public void MyTypedServerRpc(Vector3 param1, Vector3[] param2)
|
||||
{
|
||||
OnTypedServer_Rpc(param1, param2);
|
||||
}
|
||||
}
|
||||
|
||||
protected override int NumberOfClients => 1;
|
||||
@@ -46,9 +54,13 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
// Setup state
|
||||
bool hasReceivedServerRpc = false;
|
||||
bool hasReceivedTypedServerRpc = false;
|
||||
bool hasReceivedClientRpcRemotely = false;
|
||||
bool hasReceivedClientRpcLocally = false;
|
||||
|
||||
var vector3 = new Vector3(1, 2, 3);
|
||||
Vector3[] vector3s = new[] { new Vector3(4, 5, 6), new Vector3(7, 8, 9) };
|
||||
|
||||
localClienRpcTestNB.OnClient_Rpc += () =>
|
||||
{
|
||||
Debug.Log("ClientRpc received on client object");
|
||||
@@ -75,9 +87,22 @@ namespace Unity.Netcode.RuntimeTests
|
||||
hasReceivedClientRpcLocally = true;
|
||||
};
|
||||
|
||||
serverClientRpcTestNB.OnTypedServer_Rpc += (param1, param2) =>
|
||||
{
|
||||
Debug.Log("TypedServerRpc received on server object");
|
||||
Assert.AreEqual(param1, vector3);
|
||||
Assert.AreEqual(param2.Length, vector3s.Length);
|
||||
Assert.AreEqual(param2[0], vector3s[0]);
|
||||
Assert.AreEqual(param2[1], vector3s[1]);
|
||||
hasReceivedTypedServerRpc = true;
|
||||
};
|
||||
|
||||
// Send ServerRpc
|
||||
localClienRpcTestNB.MyServerRpc(m_ClientNetworkManagers[0].LocalClientId);
|
||||
|
||||
// Send TypedServerRpc
|
||||
localClienRpcTestNB.MyTypedServerRpc(vector3, vector3s);
|
||||
|
||||
// Send ClientRpc
|
||||
serverClientRpcTestNB.MyClientRpc();
|
||||
|
||||
@@ -86,6 +111,11 @@ namespace Unity.Netcode.RuntimeTests
|
||||
var serverMessageHookEntry = new MessageHookEntry(m_ServerNetworkManager);
|
||||
serverMessageHookEntry.AssignMessageType<ServerRpcMessage>();
|
||||
messageHookList.Add(serverMessageHookEntry);
|
||||
|
||||
var typedServerMessageHookEntry = new MessageHookEntry(m_ServerNetworkManager);
|
||||
typedServerMessageHookEntry.AssignMessageType<ServerRpcMessage>();
|
||||
messageHookList.Add(typedServerMessageHookEntry);
|
||||
|
||||
foreach (var client in m_ClientNetworkManagers)
|
||||
{
|
||||
var clientMessageHookEntry = new MessageHookEntry(client);
|
||||
@@ -97,9 +127,10 @@ namespace Unity.Netcode.RuntimeTests
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for messages: {rpcMessageHooks.GetHooksStillWaiting()}");
|
||||
|
||||
// Make sure RPCs propagated all the way up and were called on the relative destination class instance
|
||||
yield return WaitForConditionOrTimeOut(() => hasReceivedServerRpc && hasReceivedClientRpcLocally && hasReceivedClientRpcRemotely);
|
||||
yield return WaitForConditionOrTimeOut(() => hasReceivedServerRpc && hasReceivedClientRpcLocally && hasReceivedClientRpcRemotely && hasReceivedTypedServerRpc);
|
||||
|
||||
Assert.True(hasReceivedServerRpc, "ServerRpc was not received");
|
||||
Assert.True(hasReceivedTypedServerRpc, "TypedServerRpc was not received");
|
||||
Assert.True(hasReceivedClientRpcLocally, "ClientRpc was not locally received on the server");
|
||||
Assert.True(hasReceivedClientRpcRemotely, "ClientRpc was not remotely received on the client");
|
||||
}
|
||||
|
||||
@@ -6,69 +6,75 @@ using Unity.Netcode.TestHelpers.Runtime;
|
||||
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
public class StopStartRuntimeTests
|
||||
public class StopStartRuntimeTests : NetcodeIntegrationTest
|
||||
{
|
||||
protected override int NumberOfClients => 1;
|
||||
|
||||
protected override void OnOneTimeSetup()
|
||||
{
|
||||
m_UseHost = false;
|
||||
base.OnOneTimeSetup();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WhenShuttingDownAndRestarting_SDKRestartsSuccessfullyAndStaysRunning()
|
||||
{ // create server and client instances
|
||||
NetcodeIntegrationTestHelpers.Create(1, out NetworkManager server, out NetworkManager[] clients);
|
||||
{
|
||||
// shutdown the server
|
||||
m_ServerNetworkManager.Shutdown();
|
||||
|
||||
try
|
||||
{
|
||||
// wait 1 frame because shutdowns are delayed
|
||||
var nextFrameNumber = Time.frameCount + 1;
|
||||
yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber);
|
||||
|
||||
// create prefab
|
||||
var gameObject = new GameObject("PlayerObject");
|
||||
var networkObject = gameObject.AddComponent<NetworkObject>();
|
||||
networkObject.DontDestroyWithOwner = true;
|
||||
NetcodeIntegrationTestHelpers.MakeNetworkObjectTestPrefab(networkObject);
|
||||
// Verify the shutdown occurred
|
||||
Assert.IsFalse(m_ServerNetworkManager.IsServer);
|
||||
Assert.IsFalse(m_ServerNetworkManager.IsListening);
|
||||
Assert.IsFalse(m_ServerNetworkManager.IsHost);
|
||||
Assert.IsFalse(m_ServerNetworkManager.IsClient);
|
||||
|
||||
server.NetworkConfig.PlayerPrefab = gameObject;
|
||||
m_ServerNetworkManager.StartServer();
|
||||
// Verify the server started
|
||||
Assert.IsTrue(m_ServerNetworkManager.IsServer);
|
||||
Assert.IsTrue(m_ServerNetworkManager.IsListening);
|
||||
|
||||
for (int i = 0; i < clients.Length; i++)
|
||||
{
|
||||
clients[i].NetworkConfig.PlayerPrefab = gameObject;
|
||||
}
|
||||
// Wait several frames / one full network tick
|
||||
yield return s_DefaultWaitForTick;
|
||||
|
||||
// start server and connect clients
|
||||
NetcodeIntegrationTestHelpers.Start(false, server, clients);
|
||||
// Verify the server is still running
|
||||
Assert.IsTrue(m_ServerNetworkManager.IsServer);
|
||||
Assert.IsTrue(m_ServerNetworkManager.IsListening);
|
||||
}
|
||||
|
||||
// wait for connection on client side
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForClientsConnected(clients);
|
||||
[UnityTest]
|
||||
public IEnumerator WhenShuttingDownTwiceAndRestarting_SDKRestartsSuccessfullyAndStaysRunning()
|
||||
{
|
||||
// shutdown the server
|
||||
m_ServerNetworkManager.Shutdown();
|
||||
|
||||
// wait for connection on server side
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForClientConnectedToServer(server);
|
||||
// wait 1 frame because shutdowns are delayed
|
||||
var nextFrameNumber = Time.frameCount + 1;
|
||||
yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber);
|
||||
|
||||
// shutdown the server
|
||||
server.Shutdown();
|
||||
// Verify the shutdown occurred
|
||||
Assert.IsFalse(m_ServerNetworkManager.IsServer);
|
||||
Assert.IsFalse(m_ServerNetworkManager.IsListening);
|
||||
Assert.IsFalse(m_ServerNetworkManager.IsHost);
|
||||
Assert.IsFalse(m_ServerNetworkManager.IsClient);
|
||||
|
||||
// wait 1 frame because shutdowns are delayed
|
||||
var nextFrameNumber = Time.frameCount + 1;
|
||||
yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber);
|
||||
// Shutdown the server again.
|
||||
m_ServerNetworkManager.Shutdown();
|
||||
|
||||
// Verify the shutdown occurred
|
||||
Assert.IsFalse(server.IsServer);
|
||||
Assert.IsFalse(server.IsListening);
|
||||
Assert.IsFalse(server.IsHost);
|
||||
Assert.IsFalse(server.IsClient);
|
||||
m_ServerNetworkManager.StartServer();
|
||||
// Verify the server started
|
||||
Assert.IsTrue(m_ServerNetworkManager.IsServer);
|
||||
Assert.IsTrue(m_ServerNetworkManager.IsListening);
|
||||
|
||||
server.StartServer();
|
||||
// Verify the server started
|
||||
Assert.IsTrue(server.IsServer);
|
||||
Assert.IsTrue(server.IsListening);
|
||||
// Wait several frames / one full network tick
|
||||
yield return s_DefaultWaitForTick;
|
||||
|
||||
// Wait several frames
|
||||
nextFrameNumber = Time.frameCount + 10;
|
||||
yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber);
|
||||
|
||||
// Verify the server is still running
|
||||
Assert.IsTrue(server.IsServer);
|
||||
Assert.IsTrue(server.IsListening);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// cleanup
|
||||
NetcodeIntegrationTestHelpers.Destroy();
|
||||
}
|
||||
// Verify the server is still running
|
||||
Assert.IsTrue(m_ServerNetworkManager.IsServer);
|
||||
Assert.IsTrue(m_ServerNetworkManager.IsListening);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,8 +89,13 @@ namespace Unity.Netcode.RuntimeTests
|
||||
// compares the two client times, only difference should be based on buffering.
|
||||
m_Client1State.AssertCheckDifference(m_Client2State, 0.2 - tickInterval, (0.1 - tickInterval), tickInterval * 2 + frameInterval * 2 + k_AdditionalTimeTolerance);
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerator OnTearDown()
|
||||
{
|
||||
// Always "shutdown in a tear-down" otherwise you can cause all proceeding tests to fail
|
||||
ShutdownAndCleanUp();
|
||||
yield return base.OnTearDown();
|
||||
}
|
||||
|
||||
// This is from NetcodeIntegrationTest but we need a custom version of this to modifiy the config
|
||||
|
||||
@@ -57,12 +57,15 @@ namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
protected override int NumberOfClients => 1;
|
||||
|
||||
private ulong m_ClientId0;
|
||||
private GameObject m_PrefabToSpawn;
|
||||
|
||||
private NetworkObject m_AsNetworkObject;
|
||||
private NetworkObject m_SpawnedAsNetworkObject;
|
||||
private NetworkObject m_SpawnedObjectOnClient;
|
||||
|
||||
private NetworkObject m_BaseAsNetworkObject;
|
||||
private NetworkObject m_BaseOnClient;
|
||||
|
||||
|
||||
protected override void OnServerAndClientsCreated()
|
||||
{
|
||||
m_PrefabToSpawn = CreateNetworkObjectPrefab("InterpTestObject");
|
||||
@@ -74,41 +77,59 @@ namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
var clientId = m_ClientNetworkManagers[0].LocalClientId;
|
||||
yield return WaitForConditionOrTimeOut(() => s_GlobalNetworkObjects.ContainsKey(clientId) &&
|
||||
s_GlobalNetworkObjects[clientId].ContainsKey(m_AsNetworkObject.NetworkObjectId));
|
||||
s_GlobalNetworkObjects[clientId].ContainsKey(m_BaseAsNetworkObject.NetworkObjectId) &&
|
||||
s_GlobalNetworkObjects[clientId].ContainsKey(m_SpawnedAsNetworkObject.NetworkObjectId));
|
||||
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for client side {nameof(NetworkObject)} ID of {m_AsNetworkObject.NetworkObjectId}");
|
||||
m_SpawnedObjectOnClient = s_GlobalNetworkObjects[clientId][m_AsNetworkObject.NetworkObjectId];
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for client side {nameof(NetworkObject)} ID of {m_SpawnedAsNetworkObject.NetworkObjectId}");
|
||||
|
||||
m_BaseOnClient = s_GlobalNetworkObjects[clientId][m_BaseAsNetworkObject.NetworkObjectId];
|
||||
// make sure the objects are set with the right network manager
|
||||
m_BaseOnClient.NetworkManagerOwner = m_ClientNetworkManagers[0];
|
||||
|
||||
m_SpawnedObjectOnClient = s_GlobalNetworkObjects[clientId][m_SpawnedAsNetworkObject.NetworkObjectId];
|
||||
// make sure the objects are set with the right network manager
|
||||
m_SpawnedObjectOnClient.NetworkManagerOwner = m_ClientNetworkManagers[0];
|
||||
|
||||
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TransformInterpolationTest()
|
||||
{
|
||||
m_ClientId0 = m_ClientNetworkManagers[0].LocalClientId;
|
||||
|
||||
// create an object
|
||||
var spawnedObject = Object.Instantiate(m_PrefabToSpawn);
|
||||
var baseObject = Object.Instantiate(m_PrefabToSpawn);
|
||||
baseObject.GetComponent<NetworkObject>().NetworkManagerOwner = m_ServerNetworkManager;
|
||||
baseObject.GetComponent<NetworkObject>().Spawn();
|
||||
|
||||
m_AsNetworkObject = spawnedObject.GetComponent<NetworkObject>();
|
||||
m_AsNetworkObject.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
m_SpawnedAsNetworkObject = spawnedObject.GetComponent<NetworkObject>();
|
||||
m_SpawnedAsNetworkObject.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
|
||||
m_AsNetworkObject.TrySetParent(baseObject);
|
||||
m_BaseAsNetworkObject = baseObject.GetComponent<NetworkObject>();
|
||||
m_BaseAsNetworkObject.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
|
||||
m_AsNetworkObject.Spawn();
|
||||
|
||||
m_SpawnedAsNetworkObject.TrySetParent(baseObject);
|
||||
|
||||
m_SpawnedAsNetworkObject.Spawn();
|
||||
|
||||
yield return RefreshNetworkObjects();
|
||||
|
||||
m_AsNetworkObject.TrySetParent(baseObject);
|
||||
m_SpawnedAsNetworkObject.TrySetParent(baseObject);
|
||||
|
||||
baseObject.GetComponent<TransformInterpolationObject>().IsFixed = true;
|
||||
spawnedObject.GetComponent<TransformInterpolationObject>().IsMoving = true;
|
||||
|
||||
// Give two seconds for the object to settle
|
||||
yield return new WaitForSeconds(2.0f);
|
||||
const float maxPlacementError = 0.01f;
|
||||
|
||||
// Wait for the base object to place itself on both instances
|
||||
while (m_BaseOnClient.transform.position.y < 1000 - maxPlacementError ||
|
||||
m_BaseOnClient.transform.position.y > 1000 + maxPlacementError ||
|
||||
baseObject.transform.position.y < 1000 - maxPlacementError ||
|
||||
baseObject.transform.position.y > 1000 + maxPlacementError)
|
||||
{
|
||||
yield return new WaitForSeconds(0.01f);
|
||||
}
|
||||
|
||||
m_SpawnedObjectOnClient.GetComponent<TransformInterpolationObject>().CheckPosition = true;
|
||||
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using Unity.Netcode.TestHelpers.Runtime;
|
||||
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
public class SIPTransportTests
|
||||
{
|
||||
[Test]
|
||||
public void SendReceiveData()
|
||||
{
|
||||
SIPTransport server = new GameObject("Server").AddComponent<SIPTransport>();
|
||||
SIPTransport client = new GameObject("Client").AddComponent<SIPTransport>();
|
||||
|
||||
server.Initialize();
|
||||
server.StartServer();
|
||||
|
||||
client.Initialize();
|
||||
client.StartClient();
|
||||
|
||||
NetworkEvent serverEvent = server.PollEvent(out ulong clientId, out _, out _);
|
||||
NetworkEvent clientEvent = client.PollEvent(out ulong serverId, out _, out _);
|
||||
|
||||
// Make sure both connected
|
||||
Assert.True(serverEvent == NetworkEvent.Connect);
|
||||
Assert.True(clientEvent == NetworkEvent.Connect);
|
||||
|
||||
// Send data
|
||||
server.Send(clientId, new ArraySegment<byte>(Encoding.ASCII.GetBytes("Hello Client")), NetworkDelivery.ReliableSequenced);
|
||||
client.Send(serverId, new ArraySegment<byte>(Encoding.ASCII.GetBytes("Hello Server")), NetworkDelivery.ReliableSequenced);
|
||||
|
||||
serverEvent = server.PollEvent(out ulong newClientId, out ArraySegment<byte> serverPayload, out _);
|
||||
clientEvent = client.PollEvent(out ulong newServerId, out ArraySegment<byte> clientPayload, out _);
|
||||
|
||||
// Make sure we got data
|
||||
Assert.True(serverEvent == NetworkEvent.Data);
|
||||
Assert.True(clientEvent == NetworkEvent.Data);
|
||||
|
||||
// Make sure the ID is correct
|
||||
Assert.True(newClientId == clientId);
|
||||
Assert.True(newServerId == serverId);
|
||||
|
||||
// Make sure the payload was correct
|
||||
Assert.That(serverPayload, Is.EquivalentTo(Encoding.ASCII.GetBytes("Hello Server")));
|
||||
Assert.That(clientPayload, Is.EquivalentTo(Encoding.ASCII.GetBytes("Hello Client")));
|
||||
|
||||
server.Shutdown();
|
||||
client.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3fe3777ca6a4f4392d6281d148d0d3c
|
||||
timeCreated: 1620385694
|
||||
@@ -31,6 +31,11 @@
|
||||
"name": "com.unity.multiplayer.tools",
|
||||
"expression": "1.0.0-pre.7",
|
||||
"define": "MULTIPLAYER_TOOLS_1_0_0_PRE_7"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.modules.physics",
|
||||
"expression": "",
|
||||
"define": "COM_UNITY_MODULES_PHYSICS"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user