From 1a63b90c959fcc8d2f2a23072d600de5c6a17c6a Mon Sep 17 00:00:00 2001 From: Luke Stampfli Date: Mon, 13 Sep 2021 12:19:08 +0100 Subject: [PATCH 1/6] feat: make networkobjectref not stateful --- .../NetworkBehaviourReference.cs | 103 +++++++ .../NetworkBehaviourReference.cs.meta | 11 + .../Serialization/NetworkObjectReference.cs | 131 +++++++++ .../NetworkObjectReference.cs.meta | 11 + .../Tests/Editor/Serialization.meta | 8 + .../Tests/Runtime/Serialization.meta | 8 + .../NetworkBehaviourReferenceTests.cs | 104 +++++++ .../NetworkBehaviourReferenceTests.cs.meta | 11 + .../NetworkObjectReferenceTests.cs | 256 ++++++++++++++++++ .../NetworkObjectReferenceTests.cs.meta | 11 + 10 files changed, 654 insertions(+) create mode 100644 com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs create mode 100644 com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs.meta create mode 100644 com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs create mode 100644 com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs.meta create mode 100644 com.unity.netcode.gameobjects/Tests/Editor/Serialization.meta create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Serialization.meta create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs.meta create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs.meta diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs new file mode 100644 index 0000000000..38c1cabae4 --- /dev/null +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs @@ -0,0 +1,103 @@ +using System; +using System.Runtime.CompilerServices; +using UnityEngine; + +namespace Unity.Netcode +{ + /// + /// A helper struct for serializing s over the network. Can be used in RPCs. + /// + public struct NetworkBehaviourReference : INetworkSerializable, IEquatable + { + private NetworkObjectReference m_NetworkObjectReference; + private ushort m_NetworkBehaviourId; + + /// + /// Creates a new instance of the struct. + /// + /// The to reference. + /// + public NetworkBehaviourReference(NetworkBehaviour networkBehaviour) + { + if (networkBehaviour == null) + { + throw new ArgumentNullException(nameof(networkBehaviour)); + } + if (networkBehaviour.NetworkObject == null) + { + throw new ArgumentException($"Cannot create {nameof(NetworkBehaviourReference)} from {nameof(NetworkBehaviour)} without a {nameof(NetworkObject)}."); + } + + m_NetworkObjectReference = networkBehaviour.NetworkObject; + m_NetworkBehaviourId = networkBehaviour.NetworkBehaviourId; + } + + /// + /// Tries to get the referenced by this reference. + /// + /// The which was found. Null if the corresponding was not found. + /// The networkmanager. Uses to resolve if null. + /// True if the was found; False if the was not found. This can happen if the corresponding has not been spawned yet. you can try getting the reference at a later point in time. + public bool TryGet(out NetworkBehaviour networkBehaviour, NetworkManager networkManager = null) + { + networkBehaviour = GetInternal(this, null); + return networkBehaviour != null; + } + + /// + /// Tries to get the referenced by this reference. + /// + /// The which was found. Null if the corresponding was not found. + /// The networkmanager. Uses to resolve if null. + /// The type of the networkBehaviour for convenience. + /// True if the was found; False if the was not found. This can happen if the corresponding has not been spawned yet. you can try getting the reference at a later point in time. + public bool TryGet(out T networkBehaviour, NetworkManager networkManager = null) where T : NetworkBehaviour + { + networkBehaviour = (T)GetInternal(this, null); + return networkBehaviour != null; + } + + /// + public void NetworkSerialize(NetworkSerializer serializer) + { + m_NetworkObjectReference.NetworkSerialize(serializer); + serializer.Serialize(ref m_NetworkBehaviourId); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static NetworkBehaviour GetInternal(NetworkBehaviourReference networkBehaviourRef, NetworkManager networkManager = null) + { + if (networkBehaviourRef.m_NetworkObjectReference.TryGet(out NetworkObject networkObject, networkManager)) + { + return networkObject.GetNetworkBehaviourAtOrderIndex(networkBehaviourRef.m_NetworkBehaviourId); + } + + return null; + } + + /// + public bool Equals(NetworkBehaviourReference other) + { + return m_NetworkObjectReference.Equals(other.m_NetworkObjectReference) && m_NetworkBehaviourId == other.m_NetworkBehaviourId; + } + + /// + public override bool Equals(object obj) + { + return obj is NetworkBehaviourReference other && Equals(other); + } + + /// + public override int GetHashCode() + { + unchecked + { + return (m_NetworkObjectReference.GetHashCode() * 397) ^ m_NetworkBehaviourId.GetHashCode(); + } + } + + public static implicit operator NetworkBehaviour(NetworkBehaviourReference networkBehaviourRef) => GetInternal(networkBehaviourRef); + + public static implicit operator NetworkBehaviourReference(NetworkBehaviour networkBehaviour) => new NetworkBehaviourReference(networkBehaviour); + } +} diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs.meta b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs.meta new file mode 100644 index 0000000000..a65b9efd02 --- /dev/null +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0a9cea52f48ea70499020aebe4073ba8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs new file mode 100644 index 0000000000..743057e2dc --- /dev/null +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs @@ -0,0 +1,131 @@ +using System; +using System.Runtime.CompilerServices; +using UnityEngine; + +namespace Unity.Netcode +{ + /// + /// A helper struct for serializing s over the network. Can be used in RPCs. + /// + public struct NetworkObjectReference : INetworkSerializable, IEquatable + { + private ulong m_NetworkObjectId; + + /// + /// The of the referenced . + /// + public ulong NetworkObjectId + { + get => m_NetworkObjectId; + internal set => m_NetworkObjectId = value; + } + + /// + /// Creates a new instance of the struct. + /// + /// The to reference. + /// + /// + public NetworkObjectReference(NetworkObject networkObject) + { + if (networkObject == null) + { + throw new ArgumentNullException(nameof(networkObject)); + } + + if (networkObject.IsSpawned == false) + { + throw new ArgumentException($"{nameof(NetworkObjectReference)} can only be created from spawned {nameof(NetworkObject)}s."); + } + + m_NetworkObjectId = networkObject.NetworkObjectId; + } + + /// + /// Creates a new instance of the struct. + /// + /// The GameObject from which the component will be referenced. + /// + /// + public NetworkObjectReference(GameObject gameObject) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + var networkObject = gameObject.GetComponent(); + + if (networkObject == null) + { + throw new ArgumentException($"Cannot create {nameof(NetworkObjectReference)} from {nameof(GameObject)} without a {nameof(NetworkObject)} component."); + } + + if (networkObject.IsSpawned == false) + { + throw new ArgumentException($"{nameof(NetworkObjectReference)} can only be created from spawned {nameof(NetworkObject)}s."); + } + + m_NetworkObjectId = networkObject.NetworkObjectId; + } + + /// + /// Tries to get the referenced by this reference. + /// + /// The which was found. Null if no object was found. + /// The networkmanager. Uses to resolve if null. + /// True if the was found; False if the was not found. This can happen if the has not been spawned yet. you can try getting the reference at a later point in time. + public bool TryGet(out NetworkObject networkObject, NetworkManager networkManager = null) + { + networkObject = Resolve(this, networkManager); + return networkObject != null; + } + + /// + public void NetworkSerialize(NetworkSerializer serializer) + { + serializer.Serialize(ref m_NetworkObjectId); + } + + /// + /// Resolves the corresponding for this reference. + /// + /// The reference. + /// The networkmanager. Uses to resolve if null. + /// The resolves . Returns null if the networkobject was not found + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static NetworkObject Resolve(NetworkObjectReference networkObjectRef, NetworkManager networkManager = null) + { + networkManager = networkManager != null ? networkManager : NetworkManager.Singleton; + networkManager.SpawnManager.SpawnedObjects.TryGetValue(networkObjectRef.m_NetworkObjectId, out NetworkObject networkObject); + + return networkObject; + } + + /// + public bool Equals(NetworkObjectReference other) + { + return m_NetworkObjectId == other.m_NetworkObjectId; + } + + /// + public override bool Equals(object obj) + { + return obj is NetworkObjectReference other && Equals(other); + } + + /// + public override int GetHashCode() + { + return m_NetworkObjectId.GetHashCode(); + } + + public static implicit operator NetworkObject(NetworkObjectReference networkObjectRef) => Resolve(networkObjectRef); + + public static implicit operator NetworkObjectReference(NetworkObject networkObject) => new NetworkObjectReference(networkObject); + + public static implicit operator GameObject(NetworkObjectReference networkObjectRef) => Resolve(networkObjectRef).gameObject; + + public static implicit operator NetworkObjectReference(GameObject gameObject) => new NetworkObjectReference(gameObject); + } +} diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs.meta b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs.meta new file mode 100644 index 0000000000..fecff26098 --- /dev/null +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 463f3b530aad5d849964ee157646818e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Serialization.meta b/com.unity.netcode.gameobjects/Tests/Editor/Serialization.meta new file mode 100644 index 0000000000..7d7569cd72 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Editor/Serialization.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: eaec51687bad3344abf179bf43b11557 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization.meta b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization.meta new file mode 100644 index 0000000000..1f1dc0f8b1 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 90d51da7691e302498265bba08c43636 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs new file mode 100644 index 0000000000..31592fb6f6 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace Unity.Netcode.RuntimeTests.Serialization +{ + /// + /// Unit tests to test: + /// - Serializing NetworkObject to NetworkObjectReference + /// - Deserializing NetworkObjectReference to NetworkObject + /// - Implicit operators of NetworkObjectReference + /// + public class NetworkBehaviourReferenceTests : IDisposable + { + private class TestNetworkBehaviour : NetworkBehaviour + { + public NetworkVariable TestVariable = new NetworkVariable(); + + public TestNetworkBehaviour rpcReceivedBehaviour; + + [ServerRpc] + public void SendReferenceServerRpc(NetworkBehaviourReference value) + { + rpcReceivedBehaviour = (TestNetworkBehaviour)value; + } + } + + [UnityTest] + public IEnumerator TestRpc() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + var testNetworkBehaviour = networkObjectContext.Object.gameObject.AddComponent(); + networkObjectContext.Object.Spawn(); + + using var otherObjectContext = UnityObjectContext.CreateNetworkObject(); + otherObjectContext.Object.Spawn(); + + testNetworkBehaviour.SendReferenceServerRpc(testNetworkBehaviour); + + // wait for rpc completion + float t = 0; + while (testNetworkBehaviour.rpcReceivedBehaviour == null) + { + t += Time.deltaTime; + if (t > 5f) + { + new AssertionException("RPC with NetworkBehaviour reference hasn't been received"); + } + + yield return null; + } + + // validate + Assert.AreEqual(testNetworkBehaviour, testNetworkBehaviour.rpcReceivedBehaviour); + } + + [Test] + public void FailSerializeNonSpawnedNetworkObject() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + var component = networkObjectContext.Object.gameObject.AddComponent(); + + Assert.Throws(() => + { + NetworkBehaviourReference outReference = component; + }); + } + + [Test] + public void FailSerializeGameObjectWithoutNetworkObject() + { + using var gameObjectContext = UnityObjectContext.CreateGameObject(); + var component = gameObjectContext.Object.gameObject.AddComponent(); + + Assert.Throws(() => + { + NetworkBehaviourReference outReference = component; + }); + } + + [Test] + public void FailSerializeNullBehaviour() + { + Assert.Throws(() => + { + NetworkBehaviourReference outReference = null; + }); + } + + public void Dispose() + { + //Stop, shutdown, and destroy + NetworkManagerHelper.ShutdownNetworkManager(); + } + + public NetworkBehaviourReferenceTests() + { + //Create, instantiate, and host + NetworkManagerHelper.StartNetworkManager(out _); + } + } +} diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs.meta new file mode 100644 index 0000000000..6ae11f3c32 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0fca807d195f9fc49a400cfce86b085d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs new file mode 100644 index 0000000000..8cfd1ddc43 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs @@ -0,0 +1,256 @@ +using System; +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Object = UnityEngine.Object; + +namespace Unity.Netcode.RuntimeTests.Serialization +{ + /// + /// Unit tests to test: + /// - Serializing NetworkObject to NetworkObjectReference + /// - Deserializing NetworkObjectReference to NetworkObject + /// - Implicit operators of NetworkObjectReference + /// + public class NetworkObjectReferenceTests : IDisposable + { + private class TestNetworkBehaviour : NetworkBehaviour + { + public NetworkVariable TestVariable = new NetworkVariable(); + + public NetworkObject RpcReceivedNetworkObject; + + public GameObject RpcReceivedGameObject; + + [ServerRpc] + public void SendReferenceServerRpc(NetworkObjectReference value) + { + RpcReceivedGameObject = value; + RpcReceivedNetworkObject = value; + } + } + + [Test] + public void TestSerializeNetworkObject() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + networkObjectContext.Object.Spawn(); + using var outStream = PooledNetworkBuffer.Get(); + using var outWriter = PooledNetworkWriter.Get(outStream); + using var inStream = PooledNetworkBuffer.Get(); + using var inReader = PooledNetworkReader.Get(inStream); + + // serialize + var outSerializer = new NetworkSerializer(outWriter); + NetworkObjectReference outReference = networkObjectContext.Object; + outReference.NetworkSerialize(outSerializer); + + // deserialize + NetworkObjectReference inReference = default; + inStream.Write(outStream.ToArray()); + inStream.Position = 0; + var inSerializer = new NetworkSerializer(inReader); + inReference.NetworkSerialize(inSerializer); + + // validate + Assert.NotNull((NetworkObject)inReference); + Assert.AreEqual(inReference.NetworkObjectId, networkObjectContext.Object.NetworkObjectId); + Assert.AreEqual(outReference, inReference); + Assert.AreEqual(networkObjectContext.Object, (NetworkObject)inReference); + } + + [Test] + public void TestSerializeGameObject() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + networkObjectContext.Object.Spawn(); + using var outStream = PooledNetworkBuffer.Get(); + using var outWriter = PooledNetworkWriter.Get(outStream); + using var inStream = PooledNetworkBuffer.Get(); + using var inReader = PooledNetworkReader.Get(inStream); + + // serialize + var outSerializer = new NetworkSerializer(outWriter); + NetworkObjectReference outReference = networkObjectContext.Object.gameObject; + outReference.NetworkSerialize(outSerializer); + + // deserialize + NetworkObjectReference inReference = default; + inStream.Write(outStream.ToArray()); + inStream.Position = 0; + var inSerializer = new NetworkSerializer(inReader); + inReference.NetworkSerialize(inSerializer); + GameObject gameObject = inReference; + + // validate + Assert.AreEqual(outReference, inReference); + Assert.AreEqual(networkObjectContext.Object.gameObject, gameObject); + } + + [Test] + public void TestTryGet() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + networkObjectContext.Object.Spawn(); + + NetworkObjectReference networkObjectReference = networkObjectContext.Object; + + Assert.True(networkObjectReference.TryGet(out NetworkObject networkObject)); + Assert.NotNull(networkObject); + networkObjectReference.TryGet(out NetworkObject result); + Assert.AreEqual(networkObject, result); + } + + [UnityTest] + public IEnumerator TestRpc() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + var testNetworkBehaviour = networkObjectContext.Object.gameObject.AddComponent(); + networkObjectContext.Object.Spawn(); + + using var otherObjectContext = UnityObjectContext.CreateNetworkObject(); + otherObjectContext.Object.Spawn(); + + testNetworkBehaviour.SendReferenceServerRpc(otherObjectContext.Object); + + // wait for rpc completion + float t = 0; + while (testNetworkBehaviour.RpcReceivedGameObject == null) + { + t += Time.deltaTime; + if (t > 5f) + { + new AssertionException("RPC with NetworkBehaviour reference hasn't been received"); + } + + yield return null; + } + + // validate + Assert.AreEqual(otherObjectContext.Object, testNetworkBehaviour.RpcReceivedNetworkObject); + Assert.AreEqual(otherObjectContext.Object.gameObject, testNetworkBehaviour.RpcReceivedGameObject); + } + + [Test] + public void TestDespawn() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + networkObjectContext.Object.Spawn(); + var originalId = networkObjectContext.Object.NetworkObjectId; + + NetworkObjectReference networkObjectReference = networkObjectContext.Object; + Assert.AreEqual(networkObjectContext.Object, (NetworkObject)networkObjectReference); + + networkObjectContext.Object.Despawn(); + Assert.IsFalse(networkObjectReference.TryGet(out NetworkObject _)); + + networkObjectContext.Object.Spawn(); + + // After spawning again the reference will still no longer work as it still points to the old object + Assert.AreNotEqual(originalId, networkObjectContext.Object.NetworkObjectId); + Assert.IsFalse(networkObjectReference.TryGet(out NetworkObject _)); + + // creating a new reference will make it work again + networkObjectReference = networkObjectContext.Object; + Assert.AreEqual(networkObjectContext.Object, (NetworkObject)networkObjectReference); + } + + [Test] + public void FailSerializeNonSpawnedNetworkObject() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + + Assert.Throws(() => + { + NetworkObjectReference outReference = networkObjectContext.Object; + }); + } + + [Test] + public void FailSerializeGameObjectWithoutNetworkObject() + { + using var gameObjectContext = UnityObjectContext.CreateGameObject(); + + Assert.Throws(() => + { + NetworkObjectReference outReference = gameObjectContext.Object; + }); + } + + [Test] + public void FailSerializeNullNetworkObject() + { + Assert.Throws(() => + { + NetworkObjectReference outReference = (NetworkObject)null; + }); + } + + [Test] + public void FailSerializeNullGameObject() + { + Assert.Throws(() => + { + NetworkObjectReference outReference = (GameObject)null; + }); + } + + public void Dispose() + { + //Stop, shutdown, and destroy + NetworkManagerHelper.ShutdownNetworkManager(); + } + + public NetworkObjectReferenceTests() + { + //Create, instantiate, and host + NetworkManagerHelper.StartNetworkManager(out _); + } + } + + /// + /// Helper method for tests to create and destroy Unity Objects. + /// + /// The type of Object this context incorporates. + public class UnityObjectContext : UnityObjectContext where T : Object + { + private T m_Object; + + internal UnityObjectContext(T unityObject, Object root) + : base(root) + { + m_Object = unityObject; + } + + public T Object => m_Object; + } + + public class UnityObjectContext : IDisposable + { + private Object m_Root; + + protected UnityObjectContext(Object root) + { + m_Root = root; + } + + public static UnityObjectContext CreateGameObject(string name = "") + { + var gameObject = new GameObject(name); + return new UnityObjectContext(gameObject, gameObject); + } + + public static UnityObjectContext CreateNetworkObject(string name = "") + { + var gameObject = new GameObject(name); + var networkObject = gameObject.AddComponent(); + return new UnityObjectContext(networkObject, gameObject); + } + + public void Dispose() + { + Object.DestroyImmediate(m_Root); + } + } +} diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs.meta new file mode 100644 index 0000000000..bcaad14452 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 182c2000b73248b4bbdd79f70ec90cd2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From b5e5465ec29476516370ae86971231b3955aa122 Mon Sep 17 00:00:00 2001 From: Luke Stampfli Date: Mon, 13 Sep 2021 12:25:54 +0100 Subject: [PATCH 2/6] fix docs --- .../Runtime/Serialization/NetworkBehaviourReference.cs | 3 ++- .../Runtime/Serialization/NetworkObjectReference.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs index 38c1cabae4..5bbc494103 100644 --- a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs @@ -5,7 +5,8 @@ namespace Unity.Netcode { /// - /// A helper struct for serializing s over the network. Can be used in RPCs. + /// A helper struct for serializing s over the network. Can be used in RPCs and . + /// Note: network ids get recycled by the NetworkManager after a while. So a reference pointing to /// public struct NetworkBehaviourReference : INetworkSerializable, IEquatable { diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs index 743057e2dc..783749ec32 100644 --- a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs @@ -5,7 +5,7 @@ namespace Unity.Netcode { /// - /// A helper struct for serializing s over the network. Can be used in RPCs. + /// A helper struct for serializing s over the network. Can be used in RPCs and . /// public struct NetworkObjectReference : INetworkSerializable, IEquatable { From 3ab7a7c246fed754fbde06ced602fb7238d7875f Mon Sep 17 00:00:00 2001 From: Luke Stampfli Date: Mon, 13 Sep 2021 13:10:55 +0100 Subject: [PATCH 3/6] =?UTF-8?q?standards.py=20=E2=80=9C=C2=AF\=5F(?= =?UTF-8?q?=E3=83=84)=5F/=C2=AF=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/Serialization/NetworkBehaviourReference.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs index 5bbc494103..596831bf8b 100644 --- a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkBehaviourReference.cs @@ -1,6 +1,5 @@ using System; using System.Runtime.CompilerServices; -using UnityEngine; namespace Unity.Netcode { From b4d70a2548df65c66811b2cf4f4d0ffd25fea87b Mon Sep 17 00:00:00 2001 From: Luke Stampfli Date: Mon, 13 Sep 2021 18:52:28 +0100 Subject: [PATCH 4/6] standards.py --- .../Components/NetworkRigidbody.cs.meta | 3 +++ .../Components/NetworkRigidbody2D.cs.meta | 3 +++ .../ClientNetworkVariable.cs.meta | 3 +++ .../Tests/Runtime/Physics.meta | 3 +++ .../Physics/NetworkRigidbody2DTest.cs.meta | 3 +++ .../Physics/NetworkRigidbodyTest.cs.meta | 3 +++ testproject/Assets/Scripts/DrawRay.cs.meta | 3 +++ .../Assets/Scripts/OnCollisionColor.cs.meta | 3 +++ testproject/Assets/Scripts/PingPongMover.cs | 23 +++++++++++++++++++ .../Assets/Scripts/PingPongMover.cs.meta | 11 +++++++++ testproject/Assets/Scripts/Spawner.cs.meta | 3 +++ .../Scripts/TriggerColorChanger.cs.meta | 3 +++ 12 files changed, 64 insertions(+) create mode 100644 com.unity.netcode.gameobjects/Components/NetworkRigidbody.cs.meta create mode 100644 com.unity.netcode.gameobjects/Components/NetworkRigidbody2D.cs.meta create mode 100644 com.unity.netcode.gameobjects/Runtime/NetworkVariable/ClientNetworkVariable.cs.meta create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Physics.meta create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbody2DTest.cs.meta create mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs.meta create mode 100644 testproject/Assets/Scripts/DrawRay.cs.meta create mode 100644 testproject/Assets/Scripts/OnCollisionColor.cs.meta create mode 100644 testproject/Assets/Scripts/PingPongMover.cs create mode 100644 testproject/Assets/Scripts/PingPongMover.cs.meta create mode 100644 testproject/Assets/Scripts/Spawner.cs.meta create mode 100644 testproject/Assets/Scripts/TriggerColorChanger.cs.meta diff --git a/com.unity.netcode.gameobjects/Components/NetworkRigidbody.cs.meta b/com.unity.netcode.gameobjects/Components/NetworkRigidbody.cs.meta new file mode 100644 index 0000000000..4063e3ae0a --- /dev/null +++ b/com.unity.netcode.gameobjects/Components/NetworkRigidbody.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 89e157e06f25461dabc7c7607145c4c3 +timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Components/NetworkRigidbody2D.cs.meta b/com.unity.netcode.gameobjects/Components/NetworkRigidbody2D.cs.meta new file mode 100644 index 0000000000..a0586a84e4 --- /dev/null +++ b/com.unity.netcode.gameobjects/Components/NetworkRigidbody2D.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 27b2c26cdbc7405c92d1f18e02a1f438 +timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/ClientNetworkVariable.cs.meta b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/ClientNetworkVariable.cs.meta new file mode 100644 index 0000000000..becd7fd1b4 --- /dev/null +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/ClientNetworkVariable.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 48746b389c2344cab8da21837548f70a +timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Physics.meta b/com.unity.netcode.gameobjects/Tests/Runtime/Physics.meta new file mode 100644 index 0000000000..275076b122 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Physics.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3337ec05abcc49a795e4b27aecabbe6a +timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbody2DTest.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbody2DTest.cs.meta new file mode 100644 index 0000000000..611ef42162 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbody2DTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 44656a33500c47dd9ecb163ba82cb6ba +timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs.meta new file mode 100644 index 0000000000..0bfdf9ac8d --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0ec62c9ad88f497aa1ade68fb9fef041 +timeCreated: 1631555524 \ No newline at end of file diff --git a/testproject/Assets/Scripts/DrawRay.cs.meta b/testproject/Assets/Scripts/DrawRay.cs.meta new file mode 100644 index 0000000000..b61c382548 --- /dev/null +++ b/testproject/Assets/Scripts/DrawRay.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3c0121545f7e4058bb06ae96223ed102 +timeCreated: 1631555524 \ No newline at end of file diff --git a/testproject/Assets/Scripts/OnCollisionColor.cs.meta b/testproject/Assets/Scripts/OnCollisionColor.cs.meta new file mode 100644 index 0000000000..a522472d28 --- /dev/null +++ b/testproject/Assets/Scripts/OnCollisionColor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 23436b25353b46099bf9ca1a520da67f +timeCreated: 1631555524 \ No newline at end of file diff --git a/testproject/Assets/Scripts/PingPongMover.cs b/testproject/Assets/Scripts/PingPongMover.cs new file mode 100644 index 0000000000..4e93ffdb6b --- /dev/null +++ b/testproject/Assets/Scripts/PingPongMover.cs @@ -0,0 +1,23 @@ +using UnityEngine; + +public class PingPongMover : MonoBehaviour +{ + public Vector3 Direction; + public float Time; + + private Vector3 m_StartPosition; + + // Start is called before the first frame update + private void Start() + { + m_StartPosition = transform.position; + } + + // Update is called once per frame + private void Update() + { + var t = Mathf.PingPong(UnityEngine.Time.time, Time); + var offset = Vector3.Lerp(Vector3.zero, Direction, t); + transform.position = m_StartPosition + offset; + } +} diff --git a/testproject/Assets/Scripts/PingPongMover.cs.meta b/testproject/Assets/Scripts/PingPongMover.cs.meta new file mode 100644 index 0000000000..2606d32f7f --- /dev/null +++ b/testproject/Assets/Scripts/PingPongMover.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1ce1983eca18fbf449477e5e138f44a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Scripts/Spawner.cs.meta b/testproject/Assets/Scripts/Spawner.cs.meta new file mode 100644 index 0000000000..52f6f49fb2 --- /dev/null +++ b/testproject/Assets/Scripts/Spawner.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a5947ee7f8ed4634bc524ef9fb65300c +timeCreated: 1631555524 \ No newline at end of file diff --git a/testproject/Assets/Scripts/TriggerColorChanger.cs.meta b/testproject/Assets/Scripts/TriggerColorChanger.cs.meta new file mode 100644 index 0000000000..0c4c46c459 --- /dev/null +++ b/testproject/Assets/Scripts/TriggerColorChanger.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7210fe7df3f042dca70f759af72627f3 +timeCreated: 1631555524 \ No newline at end of file From 088c6ea0c3a31a925acc223dfe3789ff88bdb0e0 Mon Sep 17 00:00:00 2001 From: Luke Stampfli Date: Mon, 13 Sep 2021 19:37:50 +0100 Subject: [PATCH 5/6] refactor: standards.py now applied correctly --- .../Components/NetworkRigidbody.cs.meta | 3 --- .../Components/NetworkRigidbody2D.cs.meta | 3 --- .../Runtime/NetworkVariable/ClientNetworkVariable.cs.meta | 3 --- com.unity.netcode.gameobjects/Tests/Runtime/Physics.meta | 3 --- .../Tests/Runtime/Physics/NetworkRigidbody2DTest.cs.meta | 3 --- .../Tests/Runtime/Physics/NetworkRigidbodyTest.cs.meta | 3 --- .../Serialization/NetworkBehaviourReferenceTests.cs | 8 ++++---- testproject/Assets/Scripts/DrawRay.cs.meta | 3 --- testproject/Assets/Scripts/OnCollisionColor.cs.meta | 3 --- testproject/Assets/Scripts/Spawner.cs.meta | 3 --- testproject/Assets/Scripts/TriggerColorChanger.cs.meta | 3 --- 11 files changed, 4 insertions(+), 34 deletions(-) delete mode 100644 com.unity.netcode.gameobjects/Components/NetworkRigidbody.cs.meta delete mode 100644 com.unity.netcode.gameobjects/Components/NetworkRigidbody2D.cs.meta delete mode 100644 com.unity.netcode.gameobjects/Runtime/NetworkVariable/ClientNetworkVariable.cs.meta delete mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Physics.meta delete mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbody2DTest.cs.meta delete mode 100644 com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs.meta delete mode 100644 testproject/Assets/Scripts/DrawRay.cs.meta delete mode 100644 testproject/Assets/Scripts/OnCollisionColor.cs.meta delete mode 100644 testproject/Assets/Scripts/Spawner.cs.meta delete mode 100644 testproject/Assets/Scripts/TriggerColorChanger.cs.meta diff --git a/com.unity.netcode.gameobjects/Components/NetworkRigidbody.cs.meta b/com.unity.netcode.gameobjects/Components/NetworkRigidbody.cs.meta deleted file mode 100644 index 4063e3ae0a..0000000000 --- a/com.unity.netcode.gameobjects/Components/NetworkRigidbody.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 89e157e06f25461dabc7c7607145c4c3 -timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Components/NetworkRigidbody2D.cs.meta b/com.unity.netcode.gameobjects/Components/NetworkRigidbody2D.cs.meta deleted file mode 100644 index a0586a84e4..0000000000 --- a/com.unity.netcode.gameobjects/Components/NetworkRigidbody2D.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 27b2c26cdbc7405c92d1f18e02a1f438 -timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/ClientNetworkVariable.cs.meta b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/ClientNetworkVariable.cs.meta deleted file mode 100644 index becd7fd1b4..0000000000 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/ClientNetworkVariable.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 48746b389c2344cab8da21837548f70a -timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Physics.meta b/com.unity.netcode.gameobjects/Tests/Runtime/Physics.meta deleted file mode 100644 index 275076b122..0000000000 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Physics.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 3337ec05abcc49a795e4b27aecabbe6a -timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbody2DTest.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbody2DTest.cs.meta deleted file mode 100644 index 611ef42162..0000000000 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbody2DTest.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 44656a33500c47dd9ecb163ba82cb6ba -timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs.meta deleted file mode 100644 index 0bfdf9ac8d..0000000000 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Physics/NetworkRigidbodyTest.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 0ec62c9ad88f497aa1ade68fb9fef041 -timeCreated: 1631555524 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs index 31592fb6f6..4cc14ebbc3 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs @@ -18,12 +18,12 @@ private class TestNetworkBehaviour : NetworkBehaviour { public NetworkVariable TestVariable = new NetworkVariable(); - public TestNetworkBehaviour rpcReceivedBehaviour; + public TestNetworkBehaviour RpcReceivedBehaviour; [ServerRpc] public void SendReferenceServerRpc(NetworkBehaviourReference value) { - rpcReceivedBehaviour = (TestNetworkBehaviour)value; + RpcReceivedBehaviour = (TestNetworkBehaviour)value; } } @@ -41,7 +41,7 @@ public IEnumerator TestRpc() // wait for rpc completion float t = 0; - while (testNetworkBehaviour.rpcReceivedBehaviour == null) + while (testNetworkBehaviour.RpcReceivedBehaviour == null) { t += Time.deltaTime; if (t > 5f) @@ -53,7 +53,7 @@ public IEnumerator TestRpc() } // validate - Assert.AreEqual(testNetworkBehaviour, testNetworkBehaviour.rpcReceivedBehaviour); + Assert.AreEqual(testNetworkBehaviour, testNetworkBehaviour.RpcReceivedBehaviour); } [Test] diff --git a/testproject/Assets/Scripts/DrawRay.cs.meta b/testproject/Assets/Scripts/DrawRay.cs.meta deleted file mode 100644 index b61c382548..0000000000 --- a/testproject/Assets/Scripts/DrawRay.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 3c0121545f7e4058bb06ae96223ed102 -timeCreated: 1631555524 \ No newline at end of file diff --git a/testproject/Assets/Scripts/OnCollisionColor.cs.meta b/testproject/Assets/Scripts/OnCollisionColor.cs.meta deleted file mode 100644 index a522472d28..0000000000 --- a/testproject/Assets/Scripts/OnCollisionColor.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 23436b25353b46099bf9ca1a520da67f -timeCreated: 1631555524 \ No newline at end of file diff --git a/testproject/Assets/Scripts/Spawner.cs.meta b/testproject/Assets/Scripts/Spawner.cs.meta deleted file mode 100644 index 52f6f49fb2..0000000000 --- a/testproject/Assets/Scripts/Spawner.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: a5947ee7f8ed4634bc524ef9fb65300c -timeCreated: 1631555524 \ No newline at end of file diff --git a/testproject/Assets/Scripts/TriggerColorChanger.cs.meta b/testproject/Assets/Scripts/TriggerColorChanger.cs.meta deleted file mode 100644 index 0c4c46c459..0000000000 --- a/testproject/Assets/Scripts/TriggerColorChanger.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 7210fe7df3f042dca70f759af72627f3 -timeCreated: 1631555524 \ No newline at end of file From 6791a5c3a2c5eab473252563e0a4577053922cab Mon Sep 17 00:00:00 2001 From: Luke Stampfli Date: Thu, 16 Sep 2021 11:29:04 +0100 Subject: [PATCH 6/6] Tests for implict operators and NetworkVariable --- .../NetworkBehaviourReferenceTests.cs | 47 +++++++++++ .../NetworkObjectReferenceTests.cs | 79 +++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs index 4cc14ebbc3..bcc7119a00 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkBehaviourReferenceTests.cs @@ -37,6 +37,35 @@ public IEnumerator TestRpc() using var otherObjectContext = UnityObjectContext.CreateNetworkObject(); otherObjectContext.Object.Spawn(); + testNetworkBehaviour.SendReferenceServerRpc(new NetworkBehaviourReference(testNetworkBehaviour)); + + // wait for rpc completion + float t = 0; + while (testNetworkBehaviour.RpcReceivedBehaviour == null) + { + t += Time.deltaTime; + if (t > 5f) + { + new AssertionException("RPC with NetworkBehaviour reference hasn't been received"); + } + + yield return null; + } + + // validate + Assert.AreEqual(testNetworkBehaviour, testNetworkBehaviour.RpcReceivedBehaviour); + } + + [UnityTest] + public IEnumerator TestRpcImplicitNetworkBehaviour() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + var testNetworkBehaviour = networkObjectContext.Object.gameObject.AddComponent(); + networkObjectContext.Object.Spawn(); + + using var otherObjectContext = UnityObjectContext.CreateNetworkObject(); + otherObjectContext.Object.Spawn(); + testNetworkBehaviour.SendReferenceServerRpc(testNetworkBehaviour); // wait for rpc completion @@ -56,6 +85,24 @@ public IEnumerator TestRpc() Assert.AreEqual(testNetworkBehaviour, testNetworkBehaviour.RpcReceivedBehaviour); } + [Test] + public void TestNetworkVariable() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + var testNetworkBehaviour = networkObjectContext.Object.gameObject.AddComponent(); + networkObjectContext.Object.Spawn(); + + using var otherObjectContext = UnityObjectContext.CreateNetworkObject(); + otherObjectContext.Object.Spawn(); + + // check default value is null + Assert.IsNull((NetworkBehaviour)testNetworkBehaviour.TestVariable.Value); + + testNetworkBehaviour.TestVariable.Value = testNetworkBehaviour; + + Assert.AreEqual((NetworkBehaviour)testNetworkBehaviour.TestVariable.Value, testNetworkBehaviour); + } + [Test] public void FailSerializeNonSpawnedNetworkObject() { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs index 8cfd1ddc43..4d2c3b3cf4 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs @@ -112,6 +112,36 @@ public IEnumerator TestRpc() using var otherObjectContext = UnityObjectContext.CreateNetworkObject(); otherObjectContext.Object.Spawn(); + testNetworkBehaviour.SendReferenceServerRpc(new NetworkObjectReference(otherObjectContext.Object)); + + // wait for rpc completion + float t = 0; + while (testNetworkBehaviour.RpcReceivedGameObject == null) + { + t += Time.deltaTime; + if (t > 5f) + { + new AssertionException("RPC with NetworkBehaviour reference hasn't been received"); + } + + yield return null; + } + + // validate + Assert.AreEqual(otherObjectContext.Object, testNetworkBehaviour.RpcReceivedNetworkObject); + Assert.AreEqual(otherObjectContext.Object.gameObject, testNetworkBehaviour.RpcReceivedGameObject); + } + + [UnityTest] + public IEnumerator TestRpcImplicitNetworkObject() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + var testNetworkBehaviour = networkObjectContext.Object.gameObject.AddComponent(); + networkObjectContext.Object.Spawn(); + + using var otherObjectContext = UnityObjectContext.CreateNetworkObject(); + otherObjectContext.Object.Spawn(); + testNetworkBehaviour.SendReferenceServerRpc(otherObjectContext.Object); // wait for rpc completion @@ -132,6 +162,55 @@ public IEnumerator TestRpc() Assert.AreEqual(otherObjectContext.Object.gameObject, testNetworkBehaviour.RpcReceivedGameObject); } + [UnityTest] + public IEnumerator TestRpcImplicitGameObject() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + var testNetworkBehaviour = networkObjectContext.Object.gameObject.AddComponent(); + networkObjectContext.Object.Spawn(); + + using var otherObjectContext = UnityObjectContext.CreateNetworkObject(); + otherObjectContext.Object.Spawn(); + + testNetworkBehaviour.SendReferenceServerRpc(otherObjectContext.Object.gameObject); + + // wait for rpc completion + float t = 0; + while (testNetworkBehaviour.RpcReceivedGameObject == null) + { + t += Time.deltaTime; + if (t > 5f) + { + new AssertionException("RPC with NetworkBehaviour reference hasn't been received"); + } + + yield return null; + } + + // validate + Assert.AreEqual(otherObjectContext.Object, testNetworkBehaviour.RpcReceivedNetworkObject); + Assert.AreEqual(otherObjectContext.Object.gameObject, testNetworkBehaviour.RpcReceivedGameObject); + } + + [Test] + public void TestNetworkVariable() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + var testNetworkBehaviour = networkObjectContext.Object.gameObject.AddComponent(); + networkObjectContext.Object.Spawn(); + + using var otherObjectContext = UnityObjectContext.CreateNetworkObject(); + otherObjectContext.Object.Spawn(); + + // check default value is null + Assert.IsNull((NetworkObject)testNetworkBehaviour.TestVariable.Value); + + testNetworkBehaviour.TestVariable.Value = networkObjectContext.Object; + + Assert.AreEqual((GameObject)testNetworkBehaviour.TestVariable.Value, networkObjectContext.Object.gameObject); + Assert.AreEqual((NetworkObject)testNetworkBehaviour.TestVariable.Value, networkObjectContext.Object); + } + [Test] public void TestDespawn() {