com.unity.netcode.gameobjects@1.0.0-pre.10
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.10] - 2022-06-21 ### Added - Added a new `OnTransportFailure` callback to `NetworkManager`. This callback is invoked when the manager's `NetworkTransport` encounters an unrecoverable error. Transport failures also cause the `NetworkManager` to shut down. Currently, this is only used by `UnityTransport` to signal a timeout of its connection to the Unity Relay servers. (#1994) - Added `NetworkEvent.TransportFailure`, which can be used by implementations of `NetworkTransport` to signal to `NetworkManager` that an unrecoverable error was encountered. (#1994) - Added test to ensure a warning occurs when nesting NetworkObjects in a NetworkPrefab (#1969) - Added `NetworkManager.RemoveNetworkPrefab(...)` to remove a prefab from the prefabs list (#1950) ### Changed - Updated `UnityTransport` dependency on `com.unity.transport` to 1.1.0. (#2025) - (API Breaking) `ConnectionApprovalCallback` is no longer an `event` and will not allow more than 1 handler registered at a time. Also, `ConnectionApprovalCallback` is now a `Func<>` taking `ConnectionApprovalRequest` in and returning `ConnectionApprovalResponse` back out (#1972) ### Removed ### Fixed - Fixed issue where dynamically spawned `NetworkObject`s could throw an exception if the scene of origin handle was zero (0) and the `NetworkObject` was already spawned. (#2017) - Fixed issue where `NetworkObject.Observers` was not being cleared when despawned. (#2009) - Fixed `NetworkAnimator` could not run in the server authoritative mode. (#2003) - Fixed issue where late joining clients would get a soft synchronization error if any in-scene placed NetworkObjects were parented under another `NetworkObject`. (#1985) - Fixed issue where `NetworkBehaviourReference` would throw a type cast exception if using `NetworkBehaviourReference.TryGet` and the component type was not found. (#1984) - Fixed `NetworkSceneManager` was not sending scene event notifications for the currently active scene and any additively loaded scenes when loading a new scene in `LoadSceneMode.Single` mode. (#1975) - Fixed issue where one or more clients disconnecting during a scene event would cause `LoadEventCompleted` or `UnloadEventCompleted` to wait until the `NetworkConfig.LoadSceneTimeOut` period before being triggered. (#1973) - Fixed issues when multiple `ConnectionApprovalCallback`s were registered (#1972) - Fixed a regression in serialization support: `FixedString`, `Vector2Int`, and `Vector3Int` types can now be used in NetworkVariables and RPCs again without requiring a `ForceNetworkSerializeByMemcpy<>` wrapper. (#1961) - Fixed generic types that inherit from NetworkBehaviour causing crashes at compile time. (#1976) - Fixed endless dialog boxes when adding a `NetworkBehaviour` to a `NetworkManager` or vice-versa. (#1947) - Fixed `NetworkAnimator` issue where it was only synchronizing parameters if the layer or state changed or was transitioning between states. (#1946) - Fixed `NetworkAnimator` issue where when it did detect a parameter had changed it would send all parameters as opposed to only the parameters that changed. (#1946) - Fixed `NetworkAnimator` issue where it was not always disposing the `NativeArray` that is allocated when spawned. (#1946) - Fixed `NetworkAnimator` issue where it was not taking the animation speed or state speed multiplier into consideration. (#1946) - Fixed `NetworkAnimator` issue where it was not properly synchronizing late joining clients if they joined while `Animator` was transitioning between states. (#1946) - Fixed `NetworkAnimator` issue where the server was not relaying changes to non-owner clients when a client was the owner. (#1946) - Fixed issue where the `PacketLoss` metric for tools would return the packet loss over a connection lifetime instead of a single frame. (#2004)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using Unity.Netcode.Editor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Unity.Netcode.EditorTests
|
||||
@@ -78,5 +80,37 @@ namespace Unity.Netcode.EditorTests
|
||||
// Clean up
|
||||
Object.DestroyImmediate(gameObject);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedNetworkObjectPrefabCheck()
|
||||
{
|
||||
// Setup
|
||||
var networkManagerObject = new GameObject(nameof(NestedNetworkObjectPrefabCheck));
|
||||
var networkManager = networkManagerObject.AddComponent<NetworkManager>();
|
||||
networkManager.NetworkConfig = new NetworkConfig();
|
||||
|
||||
var parent = new GameObject("Parent").AddComponent<NetworkObject>();
|
||||
var child = new GameObject("Child").AddComponent<NetworkObject>();
|
||||
|
||||
// Set parent
|
||||
child.transform.SetParent(parent.transform);
|
||||
|
||||
// Make it a prefab, warning only applies to prefabs
|
||||
networkManager.AddNetworkPrefab(parent.gameObject);
|
||||
|
||||
// Mark scene as dirty to ensure OnValidate actually runs
|
||||
EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
|
||||
|
||||
// Force OnValidate
|
||||
networkManager.OnValidate();
|
||||
|
||||
// Expect a warning
|
||||
LogAssert.Expect(LogType.Warning, $"[Netcode] {NetworkManager.PrefabDebugHelper(networkManager.NetworkConfig.NetworkPrefabs[0])} has child {nameof(NetworkObject)}(s) but they will not be spawned across the network (unsupported {nameof(NetworkPrefab)} setup)");
|
||||
|
||||
// Clean up
|
||||
Object.DestroyImmediate(networkManagerObject);
|
||||
Object.DestroyImmediate(parent);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +220,14 @@ namespace Unity.Netcode.EditorTests
|
||||
{
|
||||
RunTestWithWriteType(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
}
|
||||
else if (testType == typeof(Vector2Int))
|
||||
{
|
||||
RunTestWithWriteType(new Vector2Int((int)random.NextDouble(), (int)random.NextDouble()), writeType);
|
||||
}
|
||||
else if (testType == typeof(Vector3Int))
|
||||
{
|
||||
RunTestWithWriteType(new Vector3Int((int)random.NextDouble(), (int)random.NextDouble(), (int)random.NextDouble()), writeType);
|
||||
}
|
||||
else if (testType == typeof(Vector4))
|
||||
{
|
||||
RunTestWithWriteType(new Vector4((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
|
||||
@@ -495,6 +503,22 @@ namespace Unity.Netcode.EditorTests
|
||||
new Vector3((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble()),
|
||||
}, writeType);
|
||||
}
|
||||
else if (testType == typeof(Vector2Int))
|
||||
{
|
||||
RunTypeTestLocal(new[]{
|
||||
new Vector2Int((int) random.NextDouble(), (int) random.NextDouble()),
|
||||
new Vector2Int((int) random.NextDouble(), (int) random.NextDouble()),
|
||||
new Vector2Int((int) random.NextDouble(), (int) random.NextDouble()),
|
||||
}, writeType);
|
||||
}
|
||||
else if (testType == typeof(Vector3Int))
|
||||
{
|
||||
RunTypeTestLocal(new[]{
|
||||
new Vector3Int((int) random.NextDouble(), (int) random.NextDouble(), (int) random.NextDouble()),
|
||||
new Vector3Int((int) random.NextDouble(), (int) random.NextDouble(), (int) random.NextDouble()),
|
||||
new Vector3Int((int) random.NextDouble(), (int) random.NextDouble(), (int) random.NextDouble()),
|
||||
}, writeType);
|
||||
}
|
||||
else if (testType == typeof(Vector4))
|
||||
{
|
||||
RunTypeTestLocal(new[]{
|
||||
|
||||
@@ -351,8 +351,9 @@ namespace Unity.Netcode.EditorTests
|
||||
[Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
|
||||
typeof(long), typeof(ulong), typeof(bool), typeof(char), typeof(float), typeof(double),
|
||||
typeof(ByteEnum), typeof(SByteEnum), typeof(ShortEnum), typeof(UShortEnum), typeof(IntEnum),
|
||||
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3), typeof(Vector4),
|
||||
typeof(Quaternion), typeof(Color), typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
|
||||
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3),
|
||||
typeof(Vector2Int), typeof(Vector3Int), typeof(Vector4), typeof(Quaternion), typeof(Color),
|
||||
typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
|
||||
Type testType,
|
||||
[Values] WriteType writeType)
|
||||
{
|
||||
@@ -364,14 +365,156 @@ namespace Unity.Netcode.EditorTests
|
||||
[Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
|
||||
typeof(long), typeof(ulong), typeof(bool), typeof(char), typeof(float), typeof(double),
|
||||
typeof(ByteEnum), typeof(SByteEnum), typeof(ShortEnum), typeof(UShortEnum), typeof(IntEnum),
|
||||
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3), typeof(Vector4),
|
||||
typeof(Quaternion), typeof(Color), typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
|
||||
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3),
|
||||
typeof(Vector2Int), typeof(Vector3Int), typeof(Vector4), typeof(Quaternion), typeof(Color),
|
||||
typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
|
||||
Type testType,
|
||||
[Values] WriteType writeType)
|
||||
{
|
||||
BaseArrayTypeTest(testType, writeType);
|
||||
}
|
||||
|
||||
|
||||
public unsafe void RunFixedStringTest<T>(T fixedStringValue, int numBytesWritten, WriteType writeType) where T : unmanaged, INativeList<byte>, IUTF8Bytes
|
||||
{
|
||||
fixedStringValue.Length = numBytesWritten;
|
||||
|
||||
var serializedValueSize = FastBufferWriter.GetWriteSize(fixedStringValue);
|
||||
|
||||
Assert.AreEqual(serializedValueSize, fixedStringValue.Length + sizeof(int));
|
||||
|
||||
var writer = new FastBufferWriter(serializedValueSize + 3, Allocator.Temp);
|
||||
using (writer)
|
||||
{
|
||||
var offset = 0;
|
||||
switch (writeType)
|
||||
{
|
||||
case WriteType.WriteDirect:
|
||||
Assert.IsTrue(writer.TryBeginWrite(serializedValueSize + 2), "Writer denied write permission");
|
||||
writer.WriteValue(fixedStringValue);
|
||||
break;
|
||||
case WriteType.WriteSafe:
|
||||
writer.WriteValueSafe(fixedStringValue);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
WriteCheckBytes(writer, serializedValueSize + offset);
|
||||
|
||||
var reader = new FastBufferReader(writer, Allocator.Temp);
|
||||
using (reader)
|
||||
{
|
||||
VerifyPositionAndLength(reader, writer.Length);
|
||||
|
||||
var result = new T();
|
||||
reader.ReadValueSafe(out result);
|
||||
Assert.AreEqual(fixedStringValue, result);
|
||||
|
||||
VerifyCheckBytes(reader, serializedValueSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(3, WriteType.WriteDirect)]
|
||||
[TestCase(5, WriteType.WriteSafe)]
|
||||
[TestCase(16, WriteType.WriteDirect)]
|
||||
[TestCase(29, WriteType.WriteSafe)]
|
||||
public void WhenReadingFixedString32Bytes_ValueIsReadCorrectly(int numBytesWritten, WriteType writeType)
|
||||
{
|
||||
// Repeats 01234567890123456789...
|
||||
string valueToTest = "";
|
||||
for (var i = 0; i < 29; ++i)
|
||||
{
|
||||
valueToTest += (i % 10).ToString();
|
||||
}
|
||||
|
||||
var fixedStringValue = new FixedString32Bytes(valueToTest);
|
||||
|
||||
RunFixedStringTest(fixedStringValue, numBytesWritten, writeType);
|
||||
}
|
||||
|
||||
[TestCase(3, WriteType.WriteDirect)]
|
||||
[TestCase(5, WriteType.WriteSafe)]
|
||||
[TestCase(16, WriteType.WriteDirect)]
|
||||
[TestCase(29, WriteType.WriteSafe)]
|
||||
[TestCase(61, WriteType.WriteSafe)]
|
||||
public void WhenReadingFixedString64Bytes_ValueIsReadCorrectly(int numBytesWritten, WriteType writeType)
|
||||
{
|
||||
// Repeats 01234567890123456789...
|
||||
string valueToTest = "";
|
||||
for (var i = 0; i < 61; ++i)
|
||||
{
|
||||
valueToTest += (i % 10).ToString();
|
||||
}
|
||||
|
||||
var fixedStringValue = new FixedString64Bytes(valueToTest);
|
||||
|
||||
RunFixedStringTest(fixedStringValue, numBytesWritten, writeType);
|
||||
}
|
||||
|
||||
[TestCase(3, WriteType.WriteDirect)]
|
||||
[TestCase(5, WriteType.WriteSafe)]
|
||||
[TestCase(16, WriteType.WriteDirect)]
|
||||
[TestCase(29, WriteType.WriteSafe)]
|
||||
[TestCase(61, WriteType.WriteSafe)]
|
||||
[TestCase(125, WriteType.WriteSafe)]
|
||||
public void WhenReadingFixedString128Bytes_ValueIsReadCorrectly(int numBytesWritten, WriteType writeType)
|
||||
{
|
||||
// Repeats 01234567890123456789...
|
||||
string valueToTest = "";
|
||||
for (var i = 0; i < 125; ++i)
|
||||
{
|
||||
valueToTest += (i % 10).ToString();
|
||||
}
|
||||
|
||||
var fixedStringValue = new FixedString128Bytes(valueToTest);
|
||||
|
||||
RunFixedStringTest(fixedStringValue, numBytesWritten, writeType);
|
||||
}
|
||||
|
||||
[TestCase(3, WriteType.WriteDirect)]
|
||||
[TestCase(5, WriteType.WriteSafe)]
|
||||
[TestCase(16, WriteType.WriteDirect)]
|
||||
[TestCase(29, WriteType.WriteSafe)]
|
||||
[TestCase(61, WriteType.WriteSafe)]
|
||||
[TestCase(125, WriteType.WriteSafe)]
|
||||
[TestCase(509, WriteType.WriteSafe)]
|
||||
public void WhenReadingFixedString512Bytes_ValueIsReadCorrectly(int numBytesWritten, WriteType writeType)
|
||||
{
|
||||
// Repeats 01234567890123456789...
|
||||
string valueToTest = "";
|
||||
for (var i = 0; i < 509; ++i)
|
||||
{
|
||||
valueToTest += (i % 10).ToString();
|
||||
}
|
||||
|
||||
var fixedStringValue = new FixedString512Bytes(valueToTest);
|
||||
|
||||
RunFixedStringTest(fixedStringValue, numBytesWritten, writeType);
|
||||
}
|
||||
|
||||
[TestCase(3, WriteType.WriteDirect)]
|
||||
[TestCase(5, WriteType.WriteSafe)]
|
||||
[TestCase(16, WriteType.WriteDirect)]
|
||||
[TestCase(29, WriteType.WriteSafe)]
|
||||
[TestCase(61, WriteType.WriteSafe)]
|
||||
[TestCase(125, WriteType.WriteSafe)]
|
||||
[TestCase(509, WriteType.WriteSafe)]
|
||||
[TestCase(4093, WriteType.WriteSafe)]
|
||||
public void WhenReadingFixedString4096Bytes_ValueIsReadCorrectly(int numBytesWritten, WriteType writeType)
|
||||
{
|
||||
// Repeats 01234567890123456789...
|
||||
string valueToTest = "";
|
||||
for (var i = 0; i < 4093; ++i)
|
||||
{
|
||||
valueToTest += (i % 10).ToString();
|
||||
}
|
||||
|
||||
var fixedStringValue = new FixedString4096Bytes(valueToTest);
|
||||
|
||||
RunFixedStringTest(fixedStringValue, numBytesWritten, writeType);
|
||||
}
|
||||
|
||||
[TestCase(false, WriteType.WriteDirect)]
|
||||
[TestCase(false, WriteType.WriteSafe)]
|
||||
[TestCase(true, WriteType.WriteDirect)]
|
||||
|
||||
@@ -257,8 +257,9 @@ namespace Unity.Netcode.EditorTests
|
||||
[Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
|
||||
typeof(long), typeof(ulong), typeof(bool), typeof(char), typeof(float), typeof(double),
|
||||
typeof(ByteEnum), typeof(SByteEnum), typeof(ShortEnum), typeof(UShortEnum), typeof(IntEnum),
|
||||
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3), typeof(Vector4),
|
||||
typeof(Quaternion), typeof(Color), typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
|
||||
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3),
|
||||
typeof(Vector2Int), typeof(Vector3Int), typeof(Vector4), typeof(Quaternion), typeof(Color),
|
||||
typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
|
||||
Type testType,
|
||||
[Values] WriteType writeType)
|
||||
{
|
||||
@@ -270,8 +271,9 @@ namespace Unity.Netcode.EditorTests
|
||||
[Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
|
||||
typeof(long), typeof(ulong), typeof(bool), typeof(char), typeof(float), typeof(double),
|
||||
typeof(ByteEnum), typeof(SByteEnum), typeof(ShortEnum), typeof(UShortEnum), typeof(IntEnum),
|
||||
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3), typeof(Vector4),
|
||||
typeof(Quaternion), typeof(Color), typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
|
||||
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3),
|
||||
typeof(Vector2Int), typeof(Vector3Int), typeof(Vector4), typeof(Quaternion), typeof(Color),
|
||||
typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
|
||||
Type testType,
|
||||
[Values] WriteType writeType)
|
||||
{
|
||||
@@ -336,6 +338,147 @@ namespace Unity.Netcode.EditorTests
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void RunFixedStringTest<T>(T fixedStringValue, int numBytesWritten, WriteType writeType) where T : unmanaged, INativeList<byte>, IUTF8Bytes
|
||||
{
|
||||
fixedStringValue.Length = numBytesWritten;
|
||||
|
||||
var serializedValueSize = FastBufferWriter.GetWriteSize(fixedStringValue);
|
||||
|
||||
Assert.AreEqual(fixedStringValue.Length + sizeof(int), serializedValueSize);
|
||||
|
||||
var writer = new FastBufferWriter(serializedValueSize + 3, Allocator.Temp);
|
||||
using (writer)
|
||||
{
|
||||
var offset = 0;
|
||||
switch (writeType)
|
||||
{
|
||||
case WriteType.WriteDirect:
|
||||
Assert.IsTrue(writer.TryBeginWrite(serializedValueSize + 2), "Writer denied write permission");
|
||||
writer.WriteValue(fixedStringValue);
|
||||
break;
|
||||
case WriteType.WriteSafe:
|
||||
writer.WriteValueSafe(fixedStringValue);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
VerifyPositionAndLength(writer, serializedValueSize + offset);
|
||||
WriteCheckBytes(writer, serializedValueSize + offset);
|
||||
|
||||
int* sizeValue = (int*)(writer.GetUnsafePtr() + offset);
|
||||
Assert.AreEqual(fixedStringValue.Length, *sizeValue);
|
||||
|
||||
byte* underlyingByteArray = writer.GetUnsafePtr() + sizeof(int) + offset;
|
||||
for (var i = 0; i < fixedStringValue.Length; ++i)
|
||||
{
|
||||
Assert.AreEqual(fixedStringValue[i], underlyingByteArray[i]);
|
||||
}
|
||||
|
||||
var underlyingArray = writer.ToArray();
|
||||
VerifyCheckBytes(underlyingArray, serializedValueSize + offset);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(3, WriteType.WriteDirect)]
|
||||
[TestCase(5, WriteType.WriteSafe)]
|
||||
[TestCase(16, WriteType.WriteDirect)]
|
||||
[TestCase(29, WriteType.WriteSafe)]
|
||||
public void WhenWritingFixedString32Bytes_ValueIsWrittenCorrectly(int numBytesWritten, WriteType writeType)
|
||||
{
|
||||
// Repeats 01234567890123456789...
|
||||
string valueToTest = "";
|
||||
for (var i = 0; i < 29; ++i)
|
||||
{
|
||||
valueToTest += (i % 10).ToString();
|
||||
}
|
||||
|
||||
var fixedStringValue = new FixedString32Bytes(valueToTest);
|
||||
|
||||
RunFixedStringTest(fixedStringValue, numBytesWritten, writeType);
|
||||
}
|
||||
|
||||
[TestCase(3, WriteType.WriteDirect)]
|
||||
[TestCase(5, WriteType.WriteSafe)]
|
||||
[TestCase(16, WriteType.WriteDirect)]
|
||||
[TestCase(29, WriteType.WriteSafe)]
|
||||
[TestCase(61, WriteType.WriteSafe)]
|
||||
public void WhenWritingFixedString64Bytes_ValueIsWrittenCorrectly(int numBytesWritten, WriteType writeType)
|
||||
{
|
||||
// Repeats 01234567890123456789...
|
||||
string valueToTest = "";
|
||||
for (var i = 0; i < 61; ++i)
|
||||
{
|
||||
valueToTest += (i % 10).ToString();
|
||||
}
|
||||
|
||||
var fixedStringValue = new FixedString64Bytes(valueToTest);
|
||||
|
||||
RunFixedStringTest(fixedStringValue, numBytesWritten, writeType);
|
||||
}
|
||||
|
||||
[TestCase(3, WriteType.WriteDirect)]
|
||||
[TestCase(5, WriteType.WriteSafe)]
|
||||
[TestCase(16, WriteType.WriteDirect)]
|
||||
[TestCase(29, WriteType.WriteSafe)]
|
||||
[TestCase(61, WriteType.WriteSafe)]
|
||||
[TestCase(125, WriteType.WriteSafe)]
|
||||
public void WhenWritingFixedString128Bytes_ValueIsWrittenCorrectly(int numBytesWritten, WriteType writeType)
|
||||
{
|
||||
// Repeats 01234567890123456789...
|
||||
string valueToTest = "";
|
||||
for (var i = 0; i < 125; ++i)
|
||||
{
|
||||
valueToTest += (i % 10).ToString();
|
||||
}
|
||||
|
||||
var fixedStringValue = new FixedString128Bytes(valueToTest);
|
||||
|
||||
RunFixedStringTest(fixedStringValue, numBytesWritten, writeType);
|
||||
}
|
||||
|
||||
[TestCase(3, WriteType.WriteDirect)]
|
||||
[TestCase(5, WriteType.WriteSafe)]
|
||||
[TestCase(16, WriteType.WriteDirect)]
|
||||
[TestCase(29, WriteType.WriteSafe)]
|
||||
[TestCase(61, WriteType.WriteSafe)]
|
||||
[TestCase(125, WriteType.WriteSafe)]
|
||||
[TestCase(509, WriteType.WriteSafe)]
|
||||
public void WhenWritingFixedString512Bytes_ValueIsWrittenCorrectly(int numBytesWritten, WriteType writeType)
|
||||
{
|
||||
// Repeats 01234567890123456789...
|
||||
string valueToTest = "";
|
||||
for (var i = 0; i < 509; ++i)
|
||||
{
|
||||
valueToTest += (i % 10).ToString();
|
||||
}
|
||||
|
||||
var fixedStringValue = new FixedString512Bytes(valueToTest);
|
||||
|
||||
RunFixedStringTest(fixedStringValue, numBytesWritten, writeType);
|
||||
}
|
||||
|
||||
[TestCase(3, WriteType.WriteDirect)]
|
||||
[TestCase(5, WriteType.WriteSafe)]
|
||||
[TestCase(16, WriteType.WriteDirect)]
|
||||
[TestCase(29, WriteType.WriteSafe)]
|
||||
[TestCase(61, WriteType.WriteSafe)]
|
||||
[TestCase(125, WriteType.WriteSafe)]
|
||||
[TestCase(509, WriteType.WriteSafe)]
|
||||
[TestCase(4093, WriteType.WriteSafe)]
|
||||
public void WhenWritingFixedString4096Bytes_ValueIsWrittenCorrectly(int numBytesWritten, WriteType writeType)
|
||||
{
|
||||
// Repeats 01234567890123456789...
|
||||
string valueToTest = "";
|
||||
for (var i = 0; i < 4093; ++i)
|
||||
{
|
||||
valueToTest += (i % 10).ToString();
|
||||
}
|
||||
|
||||
var fixedStringValue = new FixedString4096Bytes(valueToTest);
|
||||
|
||||
RunFixedStringTest(fixedStringValue, numBytesWritten, writeType);
|
||||
}
|
||||
|
||||
[TestCase(1, 0)]
|
||||
[TestCase(2, 0)]
|
||||
[TestCase(3, 0)]
|
||||
|
||||
136
Tests/Runtime/AddNetworkPrefabTests.cs
Normal file
136
Tests/Runtime/AddNetworkPrefabTests.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using Unity.Netcode.TestHelpers.Runtime;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
public class AddNetworkPrefabTest : NetcodeIntegrationTest
|
||||
{
|
||||
public class EmptyComponent : NetworkBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
protected override int NumberOfClients => 1;
|
||||
|
||||
private GameObject m_Prefab;
|
||||
|
||||
protected override IEnumerator OnSetup()
|
||||
{
|
||||
// Host is irrelevant, messages don't get sent to the host "client"
|
||||
m_UseHost = false;
|
||||
|
||||
m_Prefab = new GameObject("Object");
|
||||
var networkObject = m_Prefab.AddComponent<NetworkObject>();
|
||||
m_Prefab.AddComponent<EmptyComponent>();
|
||||
|
||||
// Make it a prefab
|
||||
NetcodeIntegrationTestHelpers.MakeNetworkObjectTestPrefab(networkObject);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
protected override void OnServerAndClientsCreated()
|
||||
{
|
||||
m_ServerNetworkManager.NetworkConfig.SpawnTimeout = 0;
|
||||
m_ServerNetworkManager.NetworkConfig.ForceSamePrefabs = false;
|
||||
foreach (var client in m_ClientNetworkManagers)
|
||||
{
|
||||
client.NetworkConfig.SpawnTimeout = 0;
|
||||
client.NetworkConfig.ForceSamePrefabs = false;
|
||||
}
|
||||
}
|
||||
|
||||
private EmptyComponent GetObjectForClient(ulong clientId)
|
||||
{
|
||||
foreach (var component in Object.FindObjectsOfType<EmptyComponent>())
|
||||
{
|
||||
if (component.IsSpawned && component.NetworkManager.LocalClientId == clientId)
|
||||
{
|
||||
return component;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void RegisterPrefab()
|
||||
{
|
||||
m_ServerNetworkManager.AddNetworkPrefab(m_Prefab);
|
||||
foreach (var client in m_ClientNetworkManagers)
|
||||
{
|
||||
client.AddNetworkPrefab(m_Prefab);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeregisterPrefab()
|
||||
{
|
||||
m_ServerNetworkManager.RemoveNetworkPrefab(m_Prefab);
|
||||
foreach (var client in m_ClientNetworkManagers)
|
||||
{
|
||||
client.RemoveNetworkPrefab(m_Prefab);
|
||||
}
|
||||
}
|
||||
|
||||
private static CoroutineRunner s_CoroutineRunner;
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WhenSpawningBeforeAddingPrefab_SpawnFails()
|
||||
{
|
||||
var serverObject = Object.Instantiate(m_Prefab);
|
||||
serverObject.GetComponent<NetworkObject>().NetworkManagerOwner = m_ServerNetworkManager;
|
||||
serverObject.GetComponent<NetworkObject>().Spawn();
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeReceived<CreateObjectMessage>(m_ClientNetworkManagers[0]);
|
||||
Assert.IsNull(GetObjectForClient(m_ClientNetworkManagers[0].LocalClientId));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WhenSpawningAfterAddingServerPrefabButBeforeAddingClientPrefab_SpawnFails()
|
||||
{
|
||||
m_ServerNetworkManager.AddNetworkPrefab(m_Prefab);
|
||||
|
||||
var serverObject = Object.Instantiate(m_Prefab);
|
||||
serverObject.GetComponent<NetworkObject>().NetworkManagerOwner = m_ServerNetworkManager;
|
||||
serverObject.GetComponent<NetworkObject>().Spawn();
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeReceived<CreateObjectMessage>(m_ClientNetworkManagers[0]);
|
||||
Assert.IsNull(GetObjectForClient(m_ClientNetworkManagers[0].LocalClientId));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WhenSpawningAfterAddingPrefabOnServerAndClient_SpawnSucceeds()
|
||||
{
|
||||
RegisterPrefab();
|
||||
|
||||
var serverObject = Object.Instantiate(m_Prefab);
|
||||
serverObject.GetComponent<NetworkObject>().NetworkManagerOwner = m_ServerNetworkManager;
|
||||
serverObject.GetComponent<NetworkObject>().Spawn();
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeHandled<CreateObjectMessage>(m_ClientNetworkManagers[0]);
|
||||
Assert.IsNotNull(GetObjectForClient(m_ClientNetworkManagers[0].LocalClientId));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WhenSpawningAfterRemovingPrefabOnClient_SpawnFails()
|
||||
{
|
||||
RegisterPrefab();
|
||||
|
||||
var serverObject = Object.Instantiate(m_Prefab);
|
||||
serverObject.GetComponent<NetworkObject>().NetworkManagerOwner = m_ServerNetworkManager;
|
||||
serverObject.GetComponent<NetworkObject>().Spawn();
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeReceived<CreateObjectMessage>(m_ClientNetworkManagers[0]);
|
||||
Assert.IsNotNull(GetObjectForClient(m_ClientNetworkManagers[0].LocalClientId));
|
||||
|
||||
serverObject.GetComponent<NetworkObject>().Despawn();
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeReceived<DestroyObjectMessage>(m_ClientNetworkManagers[0]);
|
||||
Assert.IsNull(GetObjectForClient(m_ClientNetworkManagers[0].LocalClientId));
|
||||
|
||||
DeregisterPrefab();
|
||||
|
||||
serverObject = Object.Instantiate(m_Prefab);
|
||||
serverObject.GetComponent<NetworkObject>().NetworkManagerOwner = m_ServerNetworkManager;
|
||||
serverObject.GetComponent<NetworkObject>().Spawn();
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeReceived<CreateObjectMessage>(m_ClientNetworkManagers[0]);
|
||||
Assert.IsNull(GetObjectForClient(m_ClientNetworkManagers[0].LocalClientId));
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Tests/Runtime/AddNetworkPrefabTests.cs.meta
Normal file
3
Tests/Runtime/AddNetworkPrefabTests.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67012fa25fe64aeda8fbf60340c1bc2f
|
||||
timeCreated: 1652205947
|
||||
@@ -24,7 +24,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
[UnityTest]
|
||||
public IEnumerator ConnectionApproval()
|
||||
{
|
||||
NetworkManagerHelper.NetworkManagerObject.ConnectionApprovalCallback += NetworkManagerObject_ConnectionApprovalCallback;
|
||||
NetworkManagerHelper.NetworkManagerObject.ConnectionApprovalCallback = NetworkManagerObject_ConnectionApprovalCallback;
|
||||
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.ConnectionApproval = true;
|
||||
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.PlayerPrefab = null;
|
||||
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.ConnectionData = Encoding.UTF8.GetBytes(m_ValidationToken.ToString());
|
||||
@@ -47,14 +47,19 @@ namespace Unity.Netcode.RuntimeTests
|
||||
Assert.True(m_IsValidated);
|
||||
}
|
||||
|
||||
private void NetworkManagerObject_ConnectionApprovalCallback(byte[] connectionData, ulong clientId, NetworkManager.ConnectionApprovedDelegate callback)
|
||||
private void NetworkManagerObject_ConnectionApprovalCallback(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
|
||||
{
|
||||
var stringGuid = Encoding.UTF8.GetString(connectionData);
|
||||
var stringGuid = Encoding.UTF8.GetString(request.Payload);
|
||||
if (m_ValidationToken.ToString() == stringGuid)
|
||||
{
|
||||
m_IsValidated = true;
|
||||
}
|
||||
callback(false, null, m_IsValidated, null, null);
|
||||
|
||||
response.Approved = m_IsValidated;
|
||||
response.CreatePlayerObject = false;
|
||||
response.Position = null;
|
||||
response.Rotation = null;
|
||||
response.PlayerPrefabHash = null;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
|
||||
@@ -878,6 +878,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
[Ignore("This test is unstable on standalones")]
|
||||
public IEnumerator WhenMultipleMessagesForTheSameObjectAreDeferredForMoreThanTheConfiguredTime_TheyAreAllRemoved([Values(1, 2, 3)] int timeout)
|
||||
{
|
||||
RegisterClientPrefabs();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using Unity.Netcode.TestHelpers.Runtime;
|
||||
@@ -12,6 +13,8 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
public class HiddenVariableObject : NetworkBehaviour
|
||||
{
|
||||
public static List<NetworkObject> ClientInstancesSpawned = new List<NetworkObject>();
|
||||
|
||||
public NetworkVariable<int> MyNetworkVariable = new NetworkVariable<int>();
|
||||
public NetworkList<int> MyNetworkList = new NetworkList<int>();
|
||||
|
||||
@@ -21,6 +24,10 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
if (!IsServer)
|
||||
{
|
||||
ClientInstancesSpawned.Add(NetworkObject);
|
||||
}
|
||||
Debug.Log($"{nameof(HiddenVariableObject)}.{nameof(OnNetworkSpawn)}() with value {MyNetworkVariable.Value}");
|
||||
|
||||
MyNetworkVariable.OnValueChanged += Changed;
|
||||
@@ -30,6 +37,15 @@ namespace Unity.Netcode.RuntimeTests
|
||||
base.OnNetworkSpawn();
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
if (!IsServer)
|
||||
{
|
||||
ClientInstancesSpawned.Remove(NetworkObject);
|
||||
}
|
||||
base.OnNetworkDespawn();
|
||||
}
|
||||
|
||||
public void Changed(int before, int after)
|
||||
{
|
||||
Debug.Log($"Value changed from {before} to {after} on {NetworkManager.LocalClientId}");
|
||||
@@ -71,50 +87,75 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
}
|
||||
|
||||
public void VerifyLists()
|
||||
public bool VerifyLists()
|
||||
{
|
||||
NetworkList<int> prev = null;
|
||||
int numComparison = 0;
|
||||
|
||||
var prevObject = (NetworkObject)null;
|
||||
// for all the instances of NetworkList
|
||||
foreach (var gameObject in m_NetSpawnedObjectOnClient)
|
||||
foreach (var networkObject in m_NetSpawnedObjectOnClient)
|
||||
{
|
||||
// this skips despawned/hidden objects
|
||||
if (gameObject != null)
|
||||
if (networkObject != null)
|
||||
{
|
||||
// if we've seen another one before
|
||||
if (prev != null)
|
||||
{
|
||||
var curr = gameObject.GetComponent<HiddenVariableObject>().MyNetworkList;
|
||||
var curr = networkObject.GetComponent<HiddenVariableObject>().MyNetworkList;
|
||||
|
||||
// check that the two lists are identical
|
||||
Debug.Assert(curr.Count == prev.Count);
|
||||
if (curr.Count != prev.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (int index = 0; index < curr.Count; index++)
|
||||
{
|
||||
Debug.Assert(curr[index] == prev[index]);
|
||||
if (curr[index] != prev[index])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
numComparison++;
|
||||
}
|
||||
prevObject = networkObject;
|
||||
// store the list
|
||||
prev = gameObject.GetComponent<HiddenVariableObject>().MyNetworkList;
|
||||
prev = networkObject.GetComponent<HiddenVariableObject>().MyNetworkList;
|
||||
}
|
||||
}
|
||||
Debug.Log($"{numComparison} comparisons done.");
|
||||
return true;
|
||||
}
|
||||
|
||||
public IEnumerator RefreshGameObects()
|
||||
public IEnumerator RefreshGameObects(int numberToExpect)
|
||||
{
|
||||
m_NetSpawnedObjectOnClient.Clear();
|
||||
yield return WaitForConditionOrTimeOut(() => numberToExpect == HiddenVariableObject.ClientInstancesSpawned.Count);
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for total spawned count to reach {numberToExpect} but is currently {HiddenVariableObject.ClientInstancesSpawned.Count}");
|
||||
m_NetSpawnedObjectOnClient = HiddenVariableObject.ClientInstancesSpawned;
|
||||
}
|
||||
|
||||
foreach (var netMan in m_ClientNetworkManagers)
|
||||
private bool CheckValueOnClient(ulong otherClientId, int value)
|
||||
{
|
||||
foreach (var id in m_ServerNetworkManager.ConnectedClientsIds)
|
||||
{
|
||||
var serverClientPlayerResult = new NetcodeIntegrationTestHelpers.ResultWrapper<NetworkObject>();
|
||||
yield return NetcodeIntegrationTestHelpers.GetNetworkObjectByRepresentation(
|
||||
x => x.NetworkObjectId == m_NetSpawnedObject.NetworkObjectId,
|
||||
netMan,
|
||||
serverClientPlayerResult);
|
||||
m_NetSpawnedObjectOnClient.Add(serverClientPlayerResult.Result);
|
||||
if (id != otherClientId)
|
||||
{
|
||||
if (!HiddenVariableObject.ValueOnClient.ContainsKey(id) || HiddenVariableObject.ValueOnClient[id] != value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private IEnumerator SetAndCheckValueSet(ulong otherClientId, int value)
|
||||
{
|
||||
yield return WaitForConditionOrTimeOut(() => CheckValueOnClient(otherClientId, value));
|
||||
Assert.IsFalse(s_GlobalTimeoutHelper.TimedOut, $"Timed out waiting for all clients to have a value of {value}");
|
||||
|
||||
yield return WaitForConditionOrTimeOut(VerifyLists);
|
||||
Assert.IsFalse(s_GlobalTimeoutHelper.TimedOut, "Timed out waiting for all clients to have identical values!");
|
||||
|
||||
Debug.Log("Value changed");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
@@ -127,15 +168,14 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
Debug.Log("Running test");
|
||||
|
||||
|
||||
// ==== Spawn object with ownership on one client
|
||||
var client = m_ServerNetworkManager.ConnectedClientsList[1];
|
||||
var otherClient = m_ServerNetworkManager.ConnectedClientsList[2];
|
||||
m_NetSpawnedObject = SpawnObject(m_TestNetworkPrefab, m_ClientNetworkManagers[1]).GetComponent<NetworkObject>();
|
||||
|
||||
yield return RefreshGameObects();
|
||||
yield return RefreshGameObects(4);
|
||||
|
||||
// === Check spawn occured
|
||||
// === Check spawn occurred
|
||||
yield return WaitForSpawnCount(NumberOfClients + 1);
|
||||
Debug.Assert(HiddenVariableObject.SpawnCount == NumberOfClients + 1);
|
||||
Debug.Log("Objects spawned");
|
||||
@@ -143,41 +183,22 @@ namespace Unity.Netcode.RuntimeTests
|
||||
// ==== Set the NetworkVariable value to 2
|
||||
HiddenVariableObject.ExpectedSize = 1;
|
||||
HiddenVariableObject.SpawnCount = 0;
|
||||
var currentValueSet = 2;
|
||||
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkVariable.Value = 2;
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkList.Add(2);
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkVariable.Value = currentValueSet;
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkList.Add(currentValueSet);
|
||||
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
|
||||
foreach (var id in m_ServerNetworkManager.ConnectedClientsIds)
|
||||
{
|
||||
Debug.Assert(HiddenVariableObject.ValueOnClient[id] == 2);
|
||||
}
|
||||
|
||||
VerifyLists();
|
||||
|
||||
Debug.Log("Value changed");
|
||||
yield return SetAndCheckValueSet(otherClient.ClientId, currentValueSet);
|
||||
|
||||
// ==== Hide our object to a different client
|
||||
HiddenVariableObject.ExpectedSize = 2;
|
||||
m_NetSpawnedObject.NetworkHide(otherClient.ClientId);
|
||||
|
||||
// ==== Change the NetworkVariable value
|
||||
// we should get one less notification of value changing and no errors or exception
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkVariable.Value = 3;
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkList.Add(3);
|
||||
currentValueSet = 3;
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkVariable.Value = currentValueSet;
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkList.Add(currentValueSet);
|
||||
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
foreach (var id in m_ServerNetworkManager.ConnectedClientsIds)
|
||||
{
|
||||
if (id != otherClient.ClientId)
|
||||
{
|
||||
Debug.Assert(HiddenVariableObject.ValueOnClient[id] == 3);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyLists();
|
||||
Debug.Log("Values changed");
|
||||
yield return SetAndCheckValueSet(otherClient.ClientId, currentValueSet);
|
||||
|
||||
// ==== Show our object again to this client
|
||||
HiddenVariableObject.ExpectedSize = 3;
|
||||
@@ -189,22 +210,13 @@ namespace Unity.Netcode.RuntimeTests
|
||||
Debug.Log("Object spawned");
|
||||
|
||||
// ==== We need a refresh for the newly re-spawned object
|
||||
yield return RefreshGameObects();
|
||||
yield return RefreshGameObects(4);
|
||||
|
||||
// ==== Change the NetworkVariable value
|
||||
// we should get all notifications of value changing and no errors or exception
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkVariable.Value = 4;
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkList.Add(4);
|
||||
currentValueSet = 4;
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkVariable.Value = currentValueSet;
|
||||
m_NetSpawnedObject.GetComponent<HiddenVariableObject>().MyNetworkList.Add(currentValueSet);
|
||||
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
|
||||
foreach (var id in m_ServerNetworkManager.ConnectedClientsIds)
|
||||
{
|
||||
Debug.Assert(HiddenVariableObject.ValueOnClient[id] == 4);
|
||||
}
|
||||
|
||||
VerifyLists();
|
||||
Debug.Log("Values changed");
|
||||
yield return SetAndCheckValueSet(otherClient.ClientId, currentValueSet);
|
||||
|
||||
// ==== Hide our object to that different client again, and then destroy it
|
||||
m_NetSpawnedObject.NetworkHide(otherClient.ClientId);
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
{
|
||||
protected override int NumberOfClients => 1;
|
||||
private readonly int m_PacketLossRate = 25;
|
||||
private int m_DropInterval = 5;
|
||||
private readonly int m_PacketLossRangeDelta = 5;
|
||||
|
||||
public PacketLossMetricsTests()
|
||||
: base(HostOrServer.Server)
|
||||
@@ -57,11 +57,12 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
[UnityTest]
|
||||
public IEnumerator TrackPacketLossAsClient()
|
||||
{
|
||||
double packetLossRate = m_PacketLossRate/100d;
|
||||
double packetLossRateMinRange = (m_PacketLossRate-m_PacketLossRangeDelta) / 100d;
|
||||
double packetLossRateMaxrange = (m_PacketLossRate + m_PacketLossRangeDelta) / 100d;
|
||||
var clientNetworkManager = m_ClientNetworkManagers[0];
|
||||
var waitForPacketLossMetric = new WaitForGaugeMetricValues((clientNetworkManager.NetworkMetrics as NetworkMetrics).Dispatcher,
|
||||
NetworkMetricTypes.PacketLoss,
|
||||
metric => Math.Abs(metric - packetLossRate) < Double.Epsilon);
|
||||
metric => packetLossRateMinRange <= metric && metric <= packetLossRateMaxrange);
|
||||
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
@@ -75,7 +76,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
|
||||
yield return waitForPacketLossMetric.WaitForMetricsReceived();
|
||||
|
||||
var packetLossValue = waitForPacketLossMetric.AssertMetricValueHaveBeenFound();
|
||||
Assert.AreEqual(packetLossRate, packetLossValue);
|
||||
Assert.That(packetLossValue, Is.InRange(packetLossRateMinRange, packetLossRateMaxrange));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,131 +3,158 @@ using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using Unity.Netcode.TestHelpers.Runtime;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
[TestFixture(HostOrServer.Host)]
|
||||
[TestFixture(HostOrServer.Server)]
|
||||
public class NetworkManagerTransportTests : NetcodeIntegrationTest
|
||||
public class NetworkManagerTransportTests
|
||||
{
|
||||
protected override int NumberOfClients => 1;
|
||||
|
||||
private bool m_CanStartServerAndClients = false;
|
||||
|
||||
public NetworkManagerTransportTests(HostOrServer hostOrServer) : base(hostOrServer) { }
|
||||
|
||||
protected override IEnumerator OnSetup()
|
||||
[Test]
|
||||
public void ClientDoesNotStartWhenTransportFails()
|
||||
{
|
||||
m_CanStartServerAndClients = false;
|
||||
return base.OnSetup();
|
||||
bool callbackInvoked = false;
|
||||
Action onTransportFailure = () => { callbackInvoked = true; };
|
||||
|
||||
var manager = new GameObject().AddComponent<NetworkManager>();
|
||||
manager.OnTransportFailure += onTransportFailure;
|
||||
|
||||
var transport = manager.gameObject.AddComponent<FailedTransport>();
|
||||
transport.FailOnStart = true;
|
||||
|
||||
manager.NetworkConfig = new NetworkConfig() { NetworkTransport = transport };
|
||||
|
||||
LogAssert.Expect(LogType.Error, $"Client is shutting down due to network transport start failure of {transport.GetType().Name}!");
|
||||
|
||||
Assert.False(manager.StartClient());
|
||||
Assert.False(manager.IsListening);
|
||||
Assert.False(manager.IsConnectedClient);
|
||||
|
||||
Assert.True(callbackInvoked);
|
||||
}
|
||||
|
||||
protected override bool CanStartServerAndClients()
|
||||
[Test]
|
||||
public void HostDoesNotStartWhenTransportFails()
|
||||
{
|
||||
return m_CanStartServerAndClients;
|
||||
bool callbackInvoked = false;
|
||||
Action onTransportFailure = () => { callbackInvoked = true; };
|
||||
|
||||
var manager = new GameObject().AddComponent<NetworkManager>();
|
||||
manager.OnTransportFailure += onTransportFailure;
|
||||
|
||||
var transport = manager.gameObject.AddComponent<FailedTransport>();
|
||||
transport.FailOnStart = true;
|
||||
|
||||
manager.NetworkConfig = new NetworkConfig() { NetworkTransport = transport };
|
||||
|
||||
LogAssert.Expect(LogType.Error, $"Server is shutting down due to network transport start failure of {transport.GetType().Name}!");
|
||||
|
||||
Assert.False(manager.StartHost());
|
||||
Assert.False(manager.IsListening);
|
||||
|
||||
Assert.True(callbackInvoked);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ServerDoesNotStartWhenTransportFails()
|
||||
{
|
||||
bool callbackInvoked = false;
|
||||
Action onTransportFailure = () => { callbackInvoked = true; };
|
||||
|
||||
var manager = new GameObject().AddComponent<NetworkManager>();
|
||||
manager.OnTransportFailure += onTransportFailure;
|
||||
|
||||
var transport = manager.gameObject.AddComponent<FailedTransport>();
|
||||
transport.FailOnStart = true;
|
||||
|
||||
manager.NetworkConfig = new NetworkConfig() { NetworkTransport = transport };
|
||||
|
||||
LogAssert.Expect(LogType.Error, $"Server is shutting down due to network transport start failure of {transport.GetType().Name}!");
|
||||
|
||||
Assert.False(manager.StartServer());
|
||||
Assert.False(manager.IsListening);
|
||||
|
||||
Assert.True(callbackInvoked);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ShutsDownWhenTransportFails()
|
||||
{
|
||||
bool callbackInvoked = false;
|
||||
Action onTransportFailure = () => { callbackInvoked = true; };
|
||||
|
||||
var manager = new GameObject().AddComponent<NetworkManager>();
|
||||
manager.OnTransportFailure += onTransportFailure;
|
||||
|
||||
var transport = manager.gameObject.AddComponent<FailedTransport>();
|
||||
transport.FailOnNextPoll = true;
|
||||
|
||||
manager.NetworkConfig = new NetworkConfig() { NetworkTransport = transport };
|
||||
|
||||
Assert.True(manager.StartServer());
|
||||
Assert.True(manager.IsListening);
|
||||
|
||||
LogAssert.Expect(LogType.Error, $"Shutting down due to network transport failure of {transport.GetType().Name}!");
|
||||
|
||||
// Need two updates to actually shut down. First one to see the transport failing, which
|
||||
// marks the NetworkManager as shutting down. Second one where actual shutdown occurs.
|
||||
yield return null;
|
||||
yield return null;
|
||||
|
||||
Assert.False(manager.IsListening);
|
||||
Assert.True(callbackInvoked);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate that if the NetworkTransport fails to start the NetworkManager
|
||||
/// will not continue the startup process and will shut itself down.
|
||||
/// Does nothing but simulate a transport that can fail at startup and/or when polling events.
|
||||
/// </summary>
|
||||
/// <param name="testClient">if true it will test the client side</param>
|
||||
[UnityTest]
|
||||
public IEnumerator DoesNotStartWhenTransportFails([Values] bool testClient)
|
||||
public class FailedTransport : TestingNetworkTransport
|
||||
{
|
||||
// The error message we should expect
|
||||
var messageToCheck = "";
|
||||
if (!testClient)
|
||||
{
|
||||
Object.DestroyImmediate(m_ServerNetworkManager.NetworkConfig.NetworkTransport);
|
||||
m_ServerNetworkManager.NetworkConfig.NetworkTransport = m_ServerNetworkManager.gameObject.AddComponent<FailedTransport>();
|
||||
m_ServerNetworkManager.NetworkConfig.NetworkTransport.Initialize(m_ServerNetworkManager);
|
||||
// The error message we should expect
|
||||
messageToCheck = $"Server is shutting down due to network transport start failure of {m_ServerNetworkManager.NetworkConfig.NetworkTransport.GetType().Name}!";
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var client in m_ClientNetworkManagers)
|
||||
{
|
||||
Object.DestroyImmediate(client.NetworkConfig.NetworkTransport);
|
||||
client.NetworkConfig.NetworkTransport = client.gameObject.AddComponent<FailedTransport>();
|
||||
client.NetworkConfig.NetworkTransport.Initialize(m_ServerNetworkManager);
|
||||
}
|
||||
// The error message we should expect
|
||||
messageToCheck = $"Client is shutting down due to network transport start failure of {m_ClientNetworkManagers[0].NetworkConfig.NetworkTransport.GetType().Name}!";
|
||||
}
|
||||
public bool FailOnStart = false;
|
||||
public bool FailOnNextPoll = false;
|
||||
|
||||
// Trap for the nested NetworkManager exception
|
||||
LogAssert.Expect(LogType.Error, messageToCheck);
|
||||
m_CanStartServerAndClients = true;
|
||||
// Due to other errors, we must not send clients if testing the server-host side
|
||||
// We can test both server and client(s) when testing client-side only
|
||||
if (testClient)
|
||||
public override bool StartClient() => !FailOnStart;
|
||||
|
||||
public override bool StartServer() => !FailOnStart;
|
||||
|
||||
public override NetworkEvent PollEvent(out ulong clientId, out ArraySegment<byte> payload, out float receiveTime)
|
||||
{
|
||||
NetcodeIntegrationTestHelpers.Start(m_UseHost, m_ServerNetworkManager, m_ClientNetworkManagers);
|
||||
yield return s_DefaultWaitForTick;
|
||||
foreach (var client in m_ClientNetworkManagers)
|
||||
clientId = 0;
|
||||
payload = new ArraySegment<byte>();
|
||||
receiveTime = 0;
|
||||
|
||||
if (FailOnNextPoll)
|
||||
{
|
||||
Assert.False(client.IsListening);
|
||||
Assert.False(client.IsConnectedClient);
|
||||
FailOnNextPoll = false;
|
||||
return NetworkEvent.TransportFailure;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NetworkEvent.Nothing;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
public override ulong ServerClientId => 0;
|
||||
|
||||
public override void Send(ulong clientId, ArraySegment<byte> payload, NetworkDelivery networkDelivery)
|
||||
{
|
||||
NetcodeIntegrationTestHelpers.Start(m_UseHost, m_ServerNetworkManager, new NetworkManager[] { });
|
||||
yield return s_DefaultWaitForTick;
|
||||
Assert.False(m_ServerNetworkManager.IsListening);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does nothing but simulate a transport that failed to start
|
||||
/// </summary>
|
||||
public class FailedTransport : TestingNetworkTransport
|
||||
{
|
||||
public override void Shutdown()
|
||||
{
|
||||
}
|
||||
public override void Initialize(NetworkManager networkManager = null)
|
||||
{
|
||||
}
|
||||
|
||||
public override ulong ServerClientId => 0;
|
||||
public override void Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
public override NetworkEvent PollEvent(out ulong clientId, out ArraySegment<byte> payload, out float receiveTime)
|
||||
{
|
||||
clientId = 0;
|
||||
payload = new ArraySegment<byte>();
|
||||
receiveTime = 0;
|
||||
return NetworkEvent.Nothing;
|
||||
}
|
||||
public override bool StartClient()
|
||||
{
|
||||
// Simulate failure, always return false
|
||||
return false;
|
||||
}
|
||||
public override bool StartServer()
|
||||
{
|
||||
// Simulate failure, always return false
|
||||
return false;
|
||||
}
|
||||
public override void Send(ulong clientId, ArraySegment<byte> payload, NetworkDelivery networkDelivery)
|
||||
{
|
||||
}
|
||||
public override ulong GetCurrentRtt(ulong clientId) => 0;
|
||||
|
||||
public override void DisconnectRemoteClient(ulong clientId)
|
||||
{
|
||||
}
|
||||
public override void DisconnectRemoteClient(ulong clientId)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Initialize(NetworkManager networkManager = null)
|
||||
{
|
||||
}
|
||||
public override ulong GetCurrentRtt(ulong clientId)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public override void DisconnectLocalClient()
|
||||
{
|
||||
public override void DisconnectLocalClient()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +168,23 @@ namespace Unity.Netcode.RuntimeTests
|
||||
Assert.False(s_GlobalTimeoutHelper.TimedOut, "Timed out while waiting for client side despawns! (2nd pass)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DynamicallySpawnedNoSceneOriginException()
|
||||
{
|
||||
var gameObject = new GameObject();
|
||||
var networkObject = gameObject.AddComponent<NetworkObject>();
|
||||
networkObject.IsSpawned = true;
|
||||
networkObject.SceneOriginHandle = 0;
|
||||
networkObject.IsSceneObject = false;
|
||||
// This validates invoking GetSceneOriginHandle will not throw an exception for a dynamically spawned NetworkObject
|
||||
// when the scene of origin handle is zero
|
||||
var sceneOriginHandle = networkObject.GetSceneOriginHandle();
|
||||
|
||||
// This validates that GetSceneOriginHandle will return the GameObject's scene handle that should be the currently active scene
|
||||
var activeSceneHandle = UnityEngine.SceneManagement.SceneManager.GetActiveScene().handle;
|
||||
Assert.IsTrue(sceneOriginHandle == activeSceneHandle, $"{nameof(NetworkObject)} should have returned the active scene handle of {activeSceneHandle} but returned {sceneOriginHandle}");
|
||||
}
|
||||
|
||||
private class TrackOnSpawnFunctions : NetworkBehaviour
|
||||
{
|
||||
public int OnNetworkSpawnCalledCount { get; private set; }
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
invalidNetworkObjects.Add(gameObject);
|
||||
|
||||
writer.WriteValueSafe((int)networkObject.gameObject.scene.handle);
|
||||
writer.WriteValueSafe((int)networkObject.GetSceneOriginHandle());
|
||||
// Serialize the invalid NetworkObject
|
||||
var sceneObject = networkObject.GetMessageSceneObject(0);
|
||||
var prePosition = writer.Position;
|
||||
@@ -85,7 +85,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
networkObjectsToTest.Add(gameObject);
|
||||
|
||||
writer.WriteValueSafe((int)networkObject.gameObject.scene.handle);
|
||||
writer.WriteValueSafe(networkObject.GetSceneOriginHandle());
|
||||
|
||||
// Handle populating the scenes loaded list
|
||||
var scene = networkObject.gameObject.scene;
|
||||
@@ -96,13 +96,13 @@ namespace Unity.Netcode.RuntimeTests
|
||||
NetworkManagerHelper.NetworkManagerObject.SceneManager.ScenesLoaded
|
||||
.Add(scene.handle, scene);
|
||||
}
|
||||
|
||||
var handle = networkObject.GetSceneOriginHandle();
|
||||
// Since this is a unit test, we will fake the server to client handle lookup by just adding the same handle key and value
|
||||
if (!NetworkManagerHelper.NetworkManagerObject.SceneManager.ServerSceneHandleToClientSceneHandle
|
||||
.ContainsKey(networkObject.gameObject.scene.handle))
|
||||
.ContainsKey(handle))
|
||||
{
|
||||
NetworkManagerHelper.NetworkManagerObject.SceneManager.ServerSceneHandleToClientSceneHandle
|
||||
.Add(networkObject.gameObject.scene.handle, networkObject.gameObject.scene.handle);
|
||||
.Add(handle, handle);
|
||||
}
|
||||
|
||||
// Serialize the valid NetworkObject
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
@@ -8,13 +8,46 @@ using Unity.Netcode.TestHelpers.Runtime;
|
||||
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
public class NetworkShowHideTest : NetworkBehaviour
|
||||
public class NetworkShowHideTestComponent : NetworkBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class ShowHideObject : NetworkBehaviour
|
||||
{
|
||||
public static List<ShowHideObject> ClientTargetedNetworkObjects = new List<ShowHideObject>();
|
||||
public static ulong ClientIdToTarget;
|
||||
|
||||
public static NetworkObject GetNetworkObjectById(ulong networkObjectId)
|
||||
{
|
||||
foreach (var entry in ClientTargetedNetworkObjects)
|
||||
{
|
||||
if (entry.NetworkObjectId == networkObjectId)
|
||||
{
|
||||
return entry.NetworkObject;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
if (NetworkManager.LocalClientId == ClientIdToTarget)
|
||||
{
|
||||
ClientTargetedNetworkObjects.Add(this);
|
||||
}
|
||||
base.OnNetworkSpawn();
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
if (ClientTargetedNetworkObjects.Contains(this))
|
||||
{
|
||||
ClientTargetedNetworkObjects.Remove(this);
|
||||
}
|
||||
base.OnNetworkDespawn();
|
||||
}
|
||||
|
||||
public NetworkVariable<int> MyNetworkVariable;
|
||||
|
||||
private void Start()
|
||||
@@ -27,7 +60,6 @@ namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
Debug.Log($"Value changed from {before} to {after}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class NetworkShowHideTests : NetcodeIntegrationTest
|
||||
@@ -46,30 +78,17 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
protected override void OnCreatePlayerPrefab()
|
||||
{
|
||||
var networkTransform = m_PlayerPrefab.AddComponent<NetworkShowHideTest>();
|
||||
var networkTransform = m_PlayerPrefab.AddComponent<NetworkShowHideTestComponent>();
|
||||
}
|
||||
|
||||
protected override void OnServerAndClientsCreated()
|
||||
{
|
||||
m_PrefabToSpawn = PreparePrefab(typeof(ShowHideObject));
|
||||
}
|
||||
|
||||
public GameObject PreparePrefab(Type type)
|
||||
{
|
||||
var prefabToSpawn = new GameObject();
|
||||
prefabToSpawn.AddComponent(type);
|
||||
var networkObjectPrefab = prefabToSpawn.AddComponent<NetworkObject>();
|
||||
NetcodeIntegrationTestHelpers.MakeNetworkObjectTestPrefab(networkObjectPrefab);
|
||||
m_ServerNetworkManager.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Prefab = prefabToSpawn });
|
||||
foreach (var clientNetworkManager in m_ClientNetworkManagers)
|
||||
{
|
||||
clientNetworkManager.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Prefab = prefabToSpawn });
|
||||
}
|
||||
return prefabToSpawn;
|
||||
m_PrefabToSpawn = CreateNetworkObjectPrefab("ShowHideObject");
|
||||
m_PrefabToSpawn.AddComponent<ShowHideObject>();
|
||||
}
|
||||
|
||||
// Check that the first client see them, or not, as expected
|
||||
private IEnumerator CheckVisible(bool target)
|
||||
private IEnumerator CheckVisible(bool isVisible)
|
||||
{
|
||||
int count = 0;
|
||||
do
|
||||
@@ -83,21 +102,31 @@ namespace Unity.Netcode.RuntimeTests
|
||||
Assert.Fail("timeout waiting for object to reach the expect visibility");
|
||||
break;
|
||||
}
|
||||
} while (m_NetSpawnedObject1.IsNetworkVisibleTo(m_ClientId0) != target ||
|
||||
m_NetSpawnedObject2.IsNetworkVisibleTo(m_ClientId0) != target ||
|
||||
m_NetSpawnedObject3.IsNetworkVisibleTo(m_ClientId0) != target ||
|
||||
m_Object1OnClient0.IsSpawned != target ||
|
||||
m_Object2OnClient0.IsSpawned != target ||
|
||||
m_Object3OnClient0.IsSpawned != target
|
||||
} while (m_NetSpawnedObject1.IsNetworkVisibleTo(m_ClientId0) != isVisible ||
|
||||
m_NetSpawnedObject2.IsNetworkVisibleTo(m_ClientId0) != isVisible ||
|
||||
m_NetSpawnedObject3.IsNetworkVisibleTo(m_ClientId0) != isVisible ||
|
||||
m_Object1OnClient0.IsSpawned != isVisible ||
|
||||
m_Object2OnClient0.IsSpawned != isVisible ||
|
||||
m_Object3OnClient0.IsSpawned != isVisible
|
||||
);
|
||||
|
||||
Debug.Assert(m_NetSpawnedObject1.IsNetworkVisibleTo(m_ClientId0) == target);
|
||||
Debug.Assert(m_NetSpawnedObject2.IsNetworkVisibleTo(m_ClientId0) == target);
|
||||
Debug.Assert(m_NetSpawnedObject3.IsNetworkVisibleTo(m_ClientId0) == target);
|
||||
Debug.Assert(m_NetSpawnedObject1.IsNetworkVisibleTo(m_ClientId0) == isVisible);
|
||||
Debug.Assert(m_NetSpawnedObject2.IsNetworkVisibleTo(m_ClientId0) == isVisible);
|
||||
Debug.Assert(m_NetSpawnedObject3.IsNetworkVisibleTo(m_ClientId0) == isVisible);
|
||||
|
||||
Debug.Assert(m_Object1OnClient0.IsSpawned == target);
|
||||
Debug.Assert(m_Object2OnClient0.IsSpawned == target);
|
||||
Debug.Assert(m_Object3OnClient0.IsSpawned == target);
|
||||
Debug.Assert(m_Object1OnClient0.IsSpawned == isVisible);
|
||||
Debug.Assert(m_Object2OnClient0.IsSpawned == isVisible);
|
||||
Debug.Assert(m_Object3OnClient0.IsSpawned == isVisible);
|
||||
|
||||
var clientNetworkManager = m_ClientNetworkManagers.Where((c) => c.LocalClientId == m_ClientId0).First();
|
||||
if (isVisible)
|
||||
{
|
||||
Assert.True(ShowHideObject.ClientTargetedNetworkObjects.Count == 3, $"Client-{clientNetworkManager.LocalClientId} should have 3 instances visible but only has {ShowHideObject.ClientTargetedNetworkObjects.Count}!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.True(ShowHideObject.ClientTargetedNetworkObjects.Count == 0, $"Client-{clientNetworkManager.LocalClientId} should have no visible instances but still has {ShowHideObject.ClientTargetedNetworkObjects.Count}!");
|
||||
}
|
||||
}
|
||||
|
||||
// Set the 3 objects visibility
|
||||
@@ -136,30 +165,19 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator RefreshNetworkObjects()
|
||||
private bool RefreshNetworkObjects()
|
||||
{
|
||||
var serverClientPlayerResult = new NetcodeIntegrationTestHelpers.ResultWrapper<NetworkObject>();
|
||||
yield return NetcodeIntegrationTestHelpers.GetNetworkObjectByRepresentation(
|
||||
x => x.NetworkObjectId == m_NetSpawnedObject1.NetworkObjectId && x.IsSpawned,
|
||||
m_ClientNetworkManagers[0],
|
||||
serverClientPlayerResult);
|
||||
m_Object1OnClient0 = serverClientPlayerResult.Result;
|
||||
yield return NetcodeIntegrationTestHelpers.GetNetworkObjectByRepresentation(
|
||||
x => x.NetworkObjectId == m_NetSpawnedObject2.NetworkObjectId && x.IsSpawned,
|
||||
m_ClientNetworkManagers[0],
|
||||
serverClientPlayerResult);
|
||||
m_Object2OnClient0 = serverClientPlayerResult.Result;
|
||||
serverClientPlayerResult = new NetcodeIntegrationTestHelpers.ResultWrapper<NetworkObject>();
|
||||
yield return NetcodeIntegrationTestHelpers.GetNetworkObjectByRepresentation(
|
||||
x => x.NetworkObjectId == m_NetSpawnedObject3.NetworkObjectId && x.IsSpawned,
|
||||
m_ClientNetworkManagers[0],
|
||||
serverClientPlayerResult);
|
||||
m_Object3OnClient0 = serverClientPlayerResult.Result;
|
||||
|
||||
// make sure the objects are set with the right network manager
|
||||
m_Object1OnClient0.NetworkManagerOwner = m_ClientNetworkManagers[0];
|
||||
m_Object2OnClient0.NetworkManagerOwner = m_ClientNetworkManagers[0];
|
||||
m_Object3OnClient0.NetworkManagerOwner = m_ClientNetworkManagers[0];
|
||||
m_Object1OnClient0 = ShowHideObject.GetNetworkObjectById(m_NetSpawnedObject1.NetworkObjectId);
|
||||
m_Object2OnClient0 = ShowHideObject.GetNetworkObjectById(m_NetSpawnedObject2.NetworkObjectId);
|
||||
m_Object3OnClient0 = ShowHideObject.GetNetworkObjectById(m_NetSpawnedObject3.NetworkObjectId);
|
||||
if (m_Object1OnClient0 == null || m_Object2OnClient0 == null || m_Object3OnClient0 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Assert.True(m_Object1OnClient0.NetworkManagerOwner == m_ClientNetworkManagers[0]);
|
||||
Assert.True(m_Object2OnClient0.NetworkManagerOwner == m_ClientNetworkManagers[0]);
|
||||
Assert.True(m_Object3OnClient0.NetworkManagerOwner == m_ClientNetworkManagers[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -167,28 +185,23 @@ namespace Unity.Netcode.RuntimeTests
|
||||
public IEnumerator NetworkShowHideTest()
|
||||
{
|
||||
m_ClientId0 = m_ClientNetworkManagers[0].LocalClientId;
|
||||
ShowHideObject.ClientTargetedNetworkObjects.Clear();
|
||||
ShowHideObject.ClientIdToTarget = m_ClientId0;
|
||||
|
||||
|
||||
// create 3 objects
|
||||
|
||||
|
||||
var spawnedObject1 = UnityEngine.Object.Instantiate(m_PrefabToSpawn);
|
||||
var spawnedObject2 = UnityEngine.Object.Instantiate(m_PrefabToSpawn);
|
||||
var spawnedObject3 = UnityEngine.Object.Instantiate(m_PrefabToSpawn);
|
||||
var spawnedObject1 = SpawnObject(m_PrefabToSpawn, m_ServerNetworkManager);
|
||||
var spawnedObject2 = SpawnObject(m_PrefabToSpawn, m_ServerNetworkManager);
|
||||
var spawnedObject3 = SpawnObject(m_PrefabToSpawn, m_ServerNetworkManager);
|
||||
m_NetSpawnedObject1 = spawnedObject1.GetComponent<NetworkObject>();
|
||||
m_NetSpawnedObject2 = spawnedObject2.GetComponent<NetworkObject>();
|
||||
m_NetSpawnedObject3 = spawnedObject3.GetComponent<NetworkObject>();
|
||||
m_NetSpawnedObject1.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
m_NetSpawnedObject2.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
m_NetSpawnedObject3.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
m_NetSpawnedObject1.Spawn();
|
||||
m_NetSpawnedObject2.Spawn();
|
||||
m_NetSpawnedObject3.Spawn();
|
||||
|
||||
|
||||
for (int mode = 0; mode < 2; mode++)
|
||||
{
|
||||
// get the NetworkObject on a client instance
|
||||
yield return RefreshNetworkObjects();
|
||||
yield return WaitForConditionOrTimeOut(RefreshNetworkObjects);
|
||||
AssertOnTimeout($"Could not refresh all NetworkObjects!");
|
||||
|
||||
// check object start visible
|
||||
yield return CheckVisible(true);
|
||||
@@ -207,7 +220,8 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
// show them to that client
|
||||
Show(mode == 0, true);
|
||||
yield return RefreshNetworkObjects();
|
||||
yield return WaitForConditionOrTimeOut(RefreshNetworkObjects);
|
||||
AssertOnTimeout($"Could not refresh all NetworkObjects!");
|
||||
|
||||
// verify they become visible
|
||||
yield return CheckVisible(true);
|
||||
@@ -218,24 +232,21 @@ namespace Unity.Netcode.RuntimeTests
|
||||
public IEnumerator NetworkShowHideQuickTest()
|
||||
{
|
||||
m_ClientId0 = m_ClientNetworkManagers[0].LocalClientId;
|
||||
ShowHideObject.ClientTargetedNetworkObjects.Clear();
|
||||
ShowHideObject.ClientIdToTarget = m_ClientId0;
|
||||
|
||||
var spawnedObject1 = UnityEngine.Object.Instantiate(m_PrefabToSpawn);
|
||||
var spawnedObject2 = UnityEngine.Object.Instantiate(m_PrefabToSpawn);
|
||||
var spawnedObject3 = UnityEngine.Object.Instantiate(m_PrefabToSpawn);
|
||||
var spawnedObject1 = SpawnObject(m_PrefabToSpawn, m_ServerNetworkManager);
|
||||
var spawnedObject2 = SpawnObject(m_PrefabToSpawn, m_ServerNetworkManager);
|
||||
var spawnedObject3 = SpawnObject(m_PrefabToSpawn, m_ServerNetworkManager);
|
||||
m_NetSpawnedObject1 = spawnedObject1.GetComponent<NetworkObject>();
|
||||
m_NetSpawnedObject2 = spawnedObject2.GetComponent<NetworkObject>();
|
||||
m_NetSpawnedObject3 = spawnedObject3.GetComponent<NetworkObject>();
|
||||
m_NetSpawnedObject1.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
m_NetSpawnedObject2.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
m_NetSpawnedObject3.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
m_NetSpawnedObject1.Spawn();
|
||||
m_NetSpawnedObject2.Spawn();
|
||||
m_NetSpawnedObject3.Spawn();
|
||||
|
||||
for (int mode = 0; mode < 2; mode++)
|
||||
{
|
||||
// get the NetworkObject on a client instance
|
||||
yield return RefreshNetworkObjects();
|
||||
yield return WaitForConditionOrTimeOut(RefreshNetworkObjects);
|
||||
AssertOnTimeout($"Could not refresh all NetworkObjects!");
|
||||
|
||||
// check object start visible
|
||||
yield return CheckVisible(true);
|
||||
@@ -245,7 +256,8 @@ namespace Unity.Netcode.RuntimeTests
|
||||
Show(mode == 0, true);
|
||||
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForTicks(m_ServerNetworkManager, 5);
|
||||
yield return RefreshNetworkObjects();
|
||||
yield return WaitForConditionOrTimeOut(RefreshNetworkObjects);
|
||||
AssertOnTimeout($"Could not refresh all NetworkObjects!");
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForTicks(m_ServerNetworkManager, 5);
|
||||
|
||||
// verify they become visible
|
||||
|
||||
@@ -267,7 +267,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnIsServerAuthoritatitive()
|
||||
protected override bool OnIsServerAuthoritative()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -271,11 +271,18 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
public class NetworkVariableTest : NetworkBehaviour
|
||||
{
|
||||
public enum SomeEnum
|
||||
{
|
||||
A,
|
||||
B,
|
||||
C
|
||||
}
|
||||
public readonly NetworkVariable<int> TheScalar = new NetworkVariable<int>();
|
||||
public readonly NetworkVariable<SomeEnum> TheEnum = new NetworkVariable<SomeEnum>();
|
||||
public readonly NetworkList<int> TheList = new NetworkList<int>();
|
||||
public readonly NetworkList<ForceNetworkSerializeByMemcpy<FixedString128Bytes>> TheLargeList = new NetworkList<ForceNetworkSerializeByMemcpy<FixedString128Bytes>>();
|
||||
public readonly NetworkList<FixedString128Bytes> TheLargeList = new NetworkList<FixedString128Bytes>();
|
||||
|
||||
public readonly NetworkVariable<ForceNetworkSerializeByMemcpy<FixedString32Bytes>> FixedString32 = new NetworkVariable<ForceNetworkSerializeByMemcpy<FixedString32Bytes>>();
|
||||
public readonly NetworkVariable<FixedString32Bytes> FixedString32 = new NetworkVariable<FixedString32Bytes>();
|
||||
|
||||
private void ListChanged(NetworkListEvent<int> e)
|
||||
{
|
||||
@@ -365,6 +372,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
// Wait for connection on client and server side
|
||||
yield return WaitForClientsConnectedOrTimeOut();
|
||||
AssertOnTimeout($"Timed-out waiting for all clients to connect!");
|
||||
|
||||
// These are the *SERVER VERSIONS* of the *CLIENT PLAYER 1 & 2*
|
||||
var result = new NetcodeIntegrationTestHelpers.ResultWrapper<NetworkObject>();
|
||||
@@ -597,7 +605,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
bool VerifyStructure()
|
||||
{
|
||||
return m_Player1OnClient1.TheStruct.Value.SomeBool == m_Player1OnServer.TheStruct.Value.SomeBool &&
|
||||
m_Player1OnClient1.TheStruct.Value.SomeInt == m_Player1OnServer.TheStruct.Value.SomeInt;
|
||||
m_Player1OnClient1.TheStruct.Value.SomeInt == m_Player1OnServer.TheStruct.Value.SomeInt;
|
||||
}
|
||||
|
||||
m_Player1OnServer.TheStruct.Value = new TestStruct() { SomeInt = k_TestUInt, SomeBool = false };
|
||||
@@ -607,6 +615,23 @@ namespace Unity.Netcode.RuntimeTests
|
||||
yield return WaitForConditionOrTimeOut(VerifyStructure);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TestNetworkVariableEnum([Values(true, false)] bool useHost)
|
||||
{
|
||||
yield return InitializeServerAndClients(useHost);
|
||||
|
||||
bool VerifyStructure()
|
||||
{
|
||||
return m_Player1OnClient1.TheEnum.Value == NetworkVariableTest.SomeEnum.C;
|
||||
}
|
||||
|
||||
m_Player1OnServer.TheEnum.Value = NetworkVariableTest.SomeEnum.C;
|
||||
m_Player1OnServer.TheEnum.SetDirty(true);
|
||||
|
||||
// Wait for the client-side to notify it is finished initializing and spawning.
|
||||
yield return WaitForConditionOrTimeOut(VerifyStructure);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TestINetworkSerializableCallsNetworkSerialize([Values(true, false)] bool useHost)
|
||||
{
|
||||
|
||||
213
Tests/Runtime/NetworkVariableUserSerializableTypesTests.cs
Normal file
213
Tests/Runtime/NetworkVariableUserSerializableTypesTests.cs
Normal file
@@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using Unity.Netcode.TestHelpers.Runtime;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Unity.Netcode.RuntimeTests
|
||||
{
|
||||
public struct MyTypeOne
|
||||
{
|
||||
public int Value;
|
||||
}
|
||||
public struct MyTypeTwo
|
||||
{
|
||||
public int Value;
|
||||
}
|
||||
public struct MyTypeThree
|
||||
{
|
||||
public int Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to help track instances of any child derived class
|
||||
/// </summary>
|
||||
public class WorkingUserNetworkVariableComponentBase : NetworkBehaviour
|
||||
{
|
||||
private static Dictionary<ulong, WorkingUserNetworkVariableComponentBase> s_Instances = new Dictionary<ulong, WorkingUserNetworkVariableComponentBase>();
|
||||
|
||||
internal static T GetRelativeInstance<T>(ulong clientId) where T : NetworkBehaviour
|
||||
{
|
||||
if (s_Instances.ContainsKey(clientId))
|
||||
{
|
||||
return s_Instances[clientId] as T;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
s_Instances.Clear();
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
if (!s_Instances.ContainsKey(NetworkManager.LocalClientId))
|
||||
{
|
||||
s_Instances.Add(NetworkManager.LocalClientId, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"{name} is spawned but client id {NetworkManager.LocalClientId} instance already exists!");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
if (s_Instances.ContainsKey(NetworkManager.LocalClientId))
|
||||
{
|
||||
s_Instances.Remove(NetworkManager.LocalClientId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"{name} is was never spawned but client id {NetworkManager.LocalClientId} is trying to despawn it!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class WorkingUserNetworkVariableComponent : WorkingUserNetworkVariableComponentBase
|
||||
{
|
||||
public NetworkVariable<MyTypeOne> NetworkVariable = new NetworkVariable<MyTypeOne>();
|
||||
}
|
||||
|
||||
public class WorkingUserNetworkVariableComponentUsingExtensionMethod : WorkingUserNetworkVariableComponentBase
|
||||
{
|
||||
public NetworkVariable<MyTypeTwo> NetworkVariable = new NetworkVariable<MyTypeTwo>();
|
||||
}
|
||||
public class NonWorkingUserNetworkVariableComponent : NetworkBehaviour
|
||||
{
|
||||
public NetworkVariable<MyTypeThree> NetworkVariable = new NetworkVariable<MyTypeThree>();
|
||||
}
|
||||
|
||||
internal static class NetworkVariableUserSerializableTypesTestsExtensionMethods
|
||||
{
|
||||
public static void WriteValueSafe(this FastBufferWriter writer, in MyTypeTwo value)
|
||||
{
|
||||
writer.WriteValueSafe(value.Value);
|
||||
}
|
||||
|
||||
public static void ReadValueSafe(this FastBufferReader reader, out MyTypeTwo value)
|
||||
{
|
||||
value = new MyTypeTwo();
|
||||
reader.ReadValueSafe(out value.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public class NetworkVariableUserSerializableTypesTests : NetcodeIntegrationTest
|
||||
{
|
||||
protected override int NumberOfClients => 1;
|
||||
|
||||
public NetworkVariableUserSerializableTypesTests()
|
||||
: base(HostOrServer.Server)
|
||||
{
|
||||
}
|
||||
|
||||
private GameObject m_WorkingPrefab;
|
||||
private GameObject m_ExtensionMethodPrefab;
|
||||
private GameObject m_NonWorkingPrefab;
|
||||
|
||||
protected override IEnumerator OnSetup()
|
||||
{
|
||||
WorkingUserNetworkVariableComponentBase.Reset();
|
||||
return base.OnSetup();
|
||||
}
|
||||
|
||||
protected override void OnServerAndClientsCreated()
|
||||
{
|
||||
m_WorkingPrefab = CreateNetworkObjectPrefab($"[{nameof(NetworkVariableUserSerializableTypesTests)}.{nameof(m_WorkingPrefab)}]");
|
||||
m_ExtensionMethodPrefab = CreateNetworkObjectPrefab($"[{nameof(NetworkVariableUserSerializableTypesTests)}.{nameof(m_ExtensionMethodPrefab)}]");
|
||||
m_NonWorkingPrefab = CreateNetworkObjectPrefab($"[{nameof(NetworkVariableUserSerializableTypesTests)}.{nameof(m_NonWorkingPrefab)}]");
|
||||
m_WorkingPrefab.AddComponent<WorkingUserNetworkVariableComponent>();
|
||||
m_ExtensionMethodPrefab.AddComponent<WorkingUserNetworkVariableComponentUsingExtensionMethod>();
|
||||
m_NonWorkingPrefab.AddComponent<NonWorkingUserNetworkVariableComponent>();
|
||||
}
|
||||
|
||||
private bool CheckForClientInstance<T>() where T : WorkingUserNetworkVariableComponentBase
|
||||
{
|
||||
var instance = WorkingUserNetworkVariableComponentBase.GetRelativeInstance<T>(m_ClientNetworkManagers[0].LocalClientId);
|
||||
return instance != null && instance.IsSpawned;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WhenUsingAUserSerializableNetworkVariableWithUserSerialization_ReplicationWorks()
|
||||
{
|
||||
UserNetworkVariableSerialization<MyTypeOne>.WriteValue = (FastBufferWriter writer, in MyTypeOne value) =>
|
||||
{
|
||||
writer.WriteValueSafe(value.Value);
|
||||
};
|
||||
UserNetworkVariableSerialization<MyTypeOne>.ReadValue = (FastBufferReader reader, out MyTypeOne value) =>
|
||||
{
|
||||
value = new MyTypeOne();
|
||||
reader.ReadValueSafe(out value.Value);
|
||||
};
|
||||
|
||||
var serverObject = SpawnObject(m_WorkingPrefab, m_ServerNetworkManager);
|
||||
var serverNetworkObject = serverObject.GetComponent<NetworkObject>();
|
||||
|
||||
// Wait for the client instance to be spawned, which removes the need to check for two NetworkVariableDeltaMessages
|
||||
yield return WaitForConditionOrTimeOut(() => CheckForClientInstance<WorkingUserNetworkVariableComponent>());
|
||||
AssertOnTimeout($"Timed out waiting for the client side object to spawn!");
|
||||
|
||||
// Get server and client instances of the test component
|
||||
var clientInstance = WorkingUserNetworkVariableComponentBase.GetRelativeInstance<WorkingUserNetworkVariableComponent>(m_ClientNetworkManagers[0].LocalClientId);
|
||||
var serverInstance = serverNetworkObject.GetComponent<WorkingUserNetworkVariableComponent>();
|
||||
|
||||
// Set the server side value
|
||||
serverInstance.NetworkVariable.Value = new MyTypeOne { Value = 20 };
|
||||
|
||||
// Wait for the NetworkVariableDeltaMessage
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeReceived<NetworkVariableDeltaMessage>(m_ClientNetworkManagers[0]);
|
||||
|
||||
// Wait for the client side value to be updated to the server side value (can take an additional frame)
|
||||
yield return WaitForConditionOrTimeOut(() => clientInstance.NetworkVariable.Value.Value == serverInstance.NetworkVariable.Value.Value);
|
||||
Assert.AreEqual(serverNetworkObject.GetComponent<WorkingUserNetworkVariableComponent>().NetworkVariable.Value.Value, clientInstance.NetworkVariable.Value.Value);
|
||||
Assert.AreEqual(20, clientInstance.NetworkVariable.Value.Value);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WhenUsingAUserSerializableNetworkVariableWithUserSerializationViaExtensionMethod_ReplicationWorks()
|
||||
{
|
||||
UserNetworkVariableSerialization<MyTypeTwo>.WriteValue = NetworkVariableUserSerializableTypesTestsExtensionMethods.WriteValueSafe;
|
||||
UserNetworkVariableSerialization<MyTypeTwo>.ReadValue = NetworkVariableUserSerializableTypesTestsExtensionMethods.ReadValueSafe;
|
||||
|
||||
var serverObject = SpawnObject(m_ExtensionMethodPrefab, m_ServerNetworkManager);
|
||||
var serverNetworkObject = serverObject.GetComponent<NetworkObject>();
|
||||
|
||||
// Wait for the client instance to be spawned, which removes the need to check for two NetworkVariableDeltaMessages
|
||||
yield return WaitForConditionOrTimeOut(() => CheckForClientInstance<WorkingUserNetworkVariableComponentUsingExtensionMethod>());
|
||||
AssertOnTimeout($"Timed out waiting for the client side object to spawn!");
|
||||
|
||||
// Get server and client instances of the test component
|
||||
var clientInstance = WorkingUserNetworkVariableComponentBase.GetRelativeInstance<WorkingUserNetworkVariableComponentUsingExtensionMethod>(m_ClientNetworkManagers[0].LocalClientId);
|
||||
var serverInstance = serverNetworkObject.GetComponent<WorkingUserNetworkVariableComponentUsingExtensionMethod>();
|
||||
// Set the server side value
|
||||
serverInstance.NetworkVariable.Value = new MyTypeTwo { Value = 20 };
|
||||
|
||||
// Wait for the NetworkVariableDeltaMessage
|
||||
yield return NetcodeIntegrationTestHelpers.WaitForMessageOfTypeReceived<NetworkVariableDeltaMessage>(m_ClientNetworkManagers[0]);
|
||||
|
||||
// Wait for the client side value to be updated to the server side value (can take an additional frame)
|
||||
yield return WaitForConditionOrTimeOut(() => clientInstance.NetworkVariable.Value.Value == serverInstance.NetworkVariable.Value.Value);
|
||||
AssertOnTimeout($"Timed out waiting for the client side object's value ({clientInstance.NetworkVariable.Value.Value}) to equal the server side objects value ({serverInstance.NetworkVariable.Value.Value})!");
|
||||
Assert.AreEqual(serverInstance.NetworkVariable.Value.Value, clientInstance.NetworkVariable.Value.Value);
|
||||
Assert.AreEqual(20, clientInstance.NetworkVariable.Value.Value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenUsingAUserSerializableNetworkVariableWithoutUserSerialization_ReplicationFails()
|
||||
{
|
||||
var serverObject = Object.Instantiate(m_NonWorkingPrefab);
|
||||
var serverNetworkObject = serverObject.GetComponent<NetworkObject>();
|
||||
serverNetworkObject.NetworkManagerOwner = m_ServerNetworkManager;
|
||||
Assert.Throws<ArgumentException>(
|
||||
() =>
|
||||
{
|
||||
serverNetworkObject.Spawn();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1195640cf744e85b58c5af6d11eeb34
|
||||
timeCreated: 1652907276
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using Unity.Collections;
|
||||
using UnityEngine.TestTools;
|
||||
using Unity.Netcode.TestHelpers.Runtime;
|
||||
using UnityEngine;
|
||||
@@ -14,7 +15,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<Vector3, Vector3[], FixedString32Bytes> OnTypedServer_Rpc;
|
||||
public event Action OnClient_Rpc;
|
||||
|
||||
[ServerRpc]
|
||||
@@ -30,9 +31,9 @@ namespace Unity.Netcode.RuntimeTests
|
||||
}
|
||||
|
||||
[ServerRpc]
|
||||
public void MyTypedServerRpc(Vector3 param1, Vector3[] param2)
|
||||
public void MyTypedServerRpc(Vector3 param1, Vector3[] param2, FixedString32Bytes param3)
|
||||
{
|
||||
OnTypedServer_Rpc(param1, param2);
|
||||
OnTypedServer_Rpc(param1, param2, param3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,13 +88,16 @@ namespace Unity.Netcode.RuntimeTests
|
||||
hasReceivedClientRpcLocally = true;
|
||||
};
|
||||
|
||||
serverClientRpcTestNB.OnTypedServer_Rpc += (param1, param2) =>
|
||||
var str = new FixedString32Bytes("abcdefg");
|
||||
|
||||
serverClientRpcTestNB.OnTypedServer_Rpc += (param1, param2, param3) =>
|
||||
{
|
||||
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]);
|
||||
Assert.AreEqual(param3, str);
|
||||
hasReceivedTypedServerRpc = true;
|
||||
};
|
||||
|
||||
@@ -101,7 +105,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
localClienRpcTestNB.MyServerRpc(m_ClientNetworkManagers[0].LocalClientId);
|
||||
|
||||
// Send TypedServerRpc
|
||||
localClienRpcTestNB.MyTypedServerRpc(vector3, vector3s);
|
||||
localClienRpcTestNB.MyTypedServerRpc(vector3, vector3s, str);
|
||||
|
||||
// Send ClientRpc
|
||||
serverClientRpcTestNB.MyClientRpc();
|
||||
|
||||
@@ -57,6 +57,9 @@ namespace Unity.Netcode.RuntimeTests
|
||||
Assert.AreEqual(testNetworkBehaviour, testNetworkBehaviour.RpcReceivedBehaviour);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TestRpcImplicitNetworkBehaviour()
|
||||
{
|
||||
@@ -149,4 +152,44 @@ namespace Unity.Netcode.RuntimeTests
|
||||
NetworkManagerHelper.StartNetworkManager(out _);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Integration tests for NetworkBehaviourReference
|
||||
/// </summary>
|
||||
public class NetworkBehaviourReferenceIntegrationTests : NetcodeIntegrationTest
|
||||
{
|
||||
protected override int NumberOfClients => 1;
|
||||
|
||||
internal class FakeMissingComponent : NetworkBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal class TestAddedComponent : NetworkBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnCreatePlayerPrefab()
|
||||
{
|
||||
m_PlayerPrefab.AddComponent<TestAddedComponent>();
|
||||
base.OnCreatePlayerPrefab();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This test validates that if a component does not exist the NetworkBehaviourReference will not throw an
|
||||
/// invalid cast exception.
|
||||
/// (It is a full integration test to assure the NetworkObjects are spawned)
|
||||
/// </summary>
|
||||
[UnityTest]
|
||||
public IEnumerator TestTryGetWithAndWithOutExistingComponent()
|
||||
{
|
||||
var networkBehaviourReference = new NetworkBehaviourReference(m_ClientNetworkManagers[0].LocalClient.PlayerObject.GetComponent<TestAddedComponent>());
|
||||
var missingComponent = (FakeMissingComponent)null;
|
||||
var testBehaviour = (TestAddedComponent)null;
|
||||
Assert.IsFalse(networkBehaviourReference.TryGet(out missingComponent));
|
||||
Assert.IsTrue(networkBehaviourReference.TryGet(out testBehaviour));
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,6 +145,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
// Wait for connection on client and server side
|
||||
yield return WaitForClientsConnectedOrTimeOut();
|
||||
AssertOnTimeout($"Timed-out waiting for all clients to connect!");
|
||||
}
|
||||
|
||||
private readonly struct NetworkTimeState : IEquatable<NetworkTimeState>
|
||||
|
||||
@@ -33,11 +33,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
// Move the nested object on the server
|
||||
if (IsMoving)
|
||||
{
|
||||
var y = Time.realtimeSinceStartup;
|
||||
while (y > 10.0f)
|
||||
{
|
||||
y -= 10.0f;
|
||||
}
|
||||
var y = Time.realtimeSinceStartup % 10.0f;
|
||||
|
||||
// change the space between local and global every second
|
||||
GetComponent<NetworkTransform>().InLocalSpace = ((int)y % 2 == 0);
|
||||
@@ -119,6 +115,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
|
||||
baseObject.GetComponent<TransformInterpolationObject>().IsFixed = true;
|
||||
spawnedObject.GetComponent<TransformInterpolationObject>().IsMoving = true;
|
||||
spawnedObject.GetComponent<NetworkTransform>().SetMaxInterpolationBound(1.0f);
|
||||
|
||||
const float maxPlacementError = 0.01f;
|
||||
|
||||
@@ -131,6 +128,7 @@ namespace Unity.Netcode.RuntimeTests
|
||||
yield return new WaitForSeconds(0.01f);
|
||||
}
|
||||
|
||||
m_SpawnedObjectOnClient.GetComponent<NetworkTransform>().SetMaxInterpolationBound(1.0f);
|
||||
m_SpawnedObjectOnClient.GetComponent<TransformInterpolationObject>().CheckPosition = true;
|
||||
|
||||
// Test that interpolation works correctly for 10 seconds
|
||||
|
||||
Reference in New Issue
Block a user