From 60bc7fe6885e4424e8dc78b9fdc59eef3123cb97 Mon Sep 17 00:00:00 2001 From: Kitty Draper Date: Fri, 26 Aug 2022 12:50:14 -0500 Subject: [PATCH 1/5] fix: Adds a null check for NetworkObjectReference => GameObject conversion [NCCBUG-172] --- .../Serialization/NetworkObjectReference.cs | 2 +- .../NetworkObjectReferenceTests.cs | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs index 11a2ab2a38..72bc580d88 100644 --- a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs @@ -139,7 +139,7 @@ public void NetworkSerialize(BufferSerializer serializer) where T : IReade /// /// The to convert from. /// This returns the that the is attached to and is referenced by the passed in as a parameter - public static implicit operator GameObject(NetworkObjectReference networkObjectRef) => Resolve(networkObjectRef).gameObject; + public static implicit operator GameObject(NetworkObjectReference networkObjectRef) => Resolve(networkObjectRef)?.gameObject; /// /// Implicitly convert to . diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs index 49c4a1f059..ca4bc47ef1 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs @@ -25,9 +25,12 @@ private class TestNetworkBehaviour : NetworkBehaviour public GameObject RpcReceivedGameObject; + public bool ReceivedRpc; + [ServerRpc] public void SendReferenceServerRpc(NetworkObjectReference value) { + ReceivedRpc = true; RpcReceivedGameObject = value; RpcReceivedNetworkObject = value; } @@ -110,6 +113,49 @@ public void TestSerializeGameObject() } } + [Test] + public void TestNoExceptionsIfObjectDisappears() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + networkObjectContext.Object.Spawn(); + + var outWriter = new FastBufferWriter(1300, Allocator.Temp); + try + { + // serialize + var outSerializer = new BufferSerializer(new BufferSerializerWriter(outWriter)); + NetworkObjectReference outReference = networkObjectContext.Object.gameObject; + outReference.NetworkSerialize(outSerializer); + + networkObjectContext.Object.Despawn(); + GameObject.DestroyImmediate(networkObjectContext.Object.gameObject); + + // deserialize + NetworkObjectReference inReference = default; + var inReader = new FastBufferReader(outWriter, Allocator.Temp); + try + { + var inSerializer = + new BufferSerializer(new BufferSerializerReader(inReader)); + inReference.NetworkSerialize(inSerializer); + } + finally + { + inReader.Dispose(); + } + GameObject gameObject = inReference; + NetworkObject networkObject = inReference; + + // because the object is gone, it won't exist on the now, so it should end up null and shouldn't throw exceptions. + Assert.AreEqual(null, networkObject); + Assert.AreEqual(null, gameObject); + } + finally + { + outWriter.Dispose(); + } + } + [Test] public void TestTryGet() { From 50faa3a830ce23a0cfc4c2c8d97e8ec78239ae2c Mon Sep 17 00:00:00 2001 From: Kitty Draper Date: Fri, 26 Aug 2022 12:52:14 -0500 Subject: [PATCH 2/5] Changelog --- com.unity.netcode.gameobjects/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 13a9476e4c..b92a070523 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -12,6 +12,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed - Fixed RPC codegen failing to choose the correct extension methods for FastBufferReader and FastBufferWriter when the parameters were a generic type (i.e., List) and extensions for multiple instantiations of that type have been defined (i.e., List and List) (#2142) +- Implicit conversion of NetworkObjectReference to GameObject will now return null instead of throwing an exception if the referenced object could not be found (i.e., was already despawned) ## [1.0.1] - 2022-08-23 From 333337eafab31abc81f10d61ba35ee0101a1062b Mon Sep 17 00:00:00 2001 From: Kitty Draper Date: Fri, 26 Aug 2022 12:53:19 -0500 Subject: [PATCH 3/5] style --- .../Runtime/Serialization/NetworkObjectReferenceTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs index ca4bc47ef1..68bdcbe605 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs @@ -118,7 +118,7 @@ public void TestNoExceptionsIfObjectDisappears() { using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); networkObjectContext.Object.Spawn(); - + var outWriter = new FastBufferWriter(1300, Allocator.Temp); try { @@ -126,9 +126,9 @@ public void TestNoExceptionsIfObjectDisappears() var outSerializer = new BufferSerializer(new BufferSerializerWriter(outWriter)); NetworkObjectReference outReference = networkObjectContext.Object.gameObject; outReference.NetworkSerialize(outSerializer); - + networkObjectContext.Object.Despawn(); - GameObject.DestroyImmediate(networkObjectContext.Object.gameObject); + Object.DestroyImmediate(networkObjectContext.Object.gameObject); // deserialize NetworkObjectReference inReference = default; From 6aacba61b7b95959197162226adbbfc66a46259d Mon Sep 17 00:00:00 2001 From: Kitty Draper <284434+ShadauxCat@users.noreply.github.com> Date: Mon, 29 Aug 2022 15:34:30 -0500 Subject: [PATCH 4/5] Update com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs Co-authored-by: Jesse Olmer --- .../NetworkObjectReferenceTests.cs | 51 +++++++------------ 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs index 68bdcbe605..0884275276 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs @@ -114,48 +114,31 @@ public void TestSerializeGameObject() } [Test] - public void TestNoExceptionsIfObjectDisappears() + public void TestImplicitConversionToGameObject() { using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); networkObjectContext.Object.Spawn(); - var outWriter = new FastBufferWriter(1300, Allocator.Temp); - try - { - // serialize - var outSerializer = new BufferSerializer(new BufferSerializerWriter(outWriter)); - NetworkObjectReference outReference = networkObjectContext.Object.gameObject; - outReference.NetworkSerialize(outSerializer); + NetworkObjectReference outReference = networkObjectContext.Object.gameObject; - networkObjectContext.Object.Despawn(); - Object.DestroyImmediate(networkObjectContext.Object.gameObject); + GameObject go = outReference; + Assert.AreEqual(networkObjectContext.Object.gameObject, go); + } - // deserialize - NetworkObjectReference inReference = default; - var inReader = new FastBufferReader(outWriter, Allocator.Temp); - try - { - var inSerializer = - new BufferSerializer(new BufferSerializerReader(inReader)); - inReference.NetworkSerialize(inSerializer); - } - finally - { - inReader.Dispose(); - } - GameObject gameObject = inReference; - NetworkObject networkObject = inReference; + [Test] + public void TestImplicitToGameObjectIsNullWhenNotFound() + { + using var networkObjectContext = UnityObjectContext.CreateNetworkObject(); + networkObjectContext.Object.Spawn(); - // because the object is gone, it won't exist on the now, so it should end up null and shouldn't throw exceptions. - Assert.AreEqual(null, networkObject); - Assert.AreEqual(null, gameObject); - } - finally - { - outWriter.Dispose(); - } - } + NetworkObjectReference outReference = networkObjectContext.Object.gameObject; + + networkObjectContext.Object.Despawn(); + Object.DestroyImmediate(networkObjectContext.Object.gameObject); + GameObject go = outReference; + Assert.IsNull(go); + } [Test] public void TestTryGet() { From a9e33a5022572461c7f9bc5e7d60812a342a4694 Mon Sep 17 00:00:00 2001 From: Kitty Draper Date: Mon, 29 Aug 2022 15:36:02 -0500 Subject: [PATCH 5/5] Review feedback. --- .../Runtime/Serialization/NetworkObjectReference.cs | 11 ++++++++++- .../Serialization/NetworkObjectReferenceTests.cs | 3 --- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs index 72bc580d88..263403589e 100644 --- a/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs +++ b/com.unity.netcode.gameobjects/Runtime/Serialization/NetworkObjectReference.cs @@ -139,7 +139,16 @@ public void NetworkSerialize(BufferSerializer serializer) where T : IReade /// /// The to convert from. /// This returns the that the is attached to and is referenced by the passed in as a parameter - public static implicit operator GameObject(NetworkObjectReference networkObjectRef) => Resolve(networkObjectRef)?.gameObject; + public static implicit operator GameObject(NetworkObjectReference networkObjectRef) + { + var networkObject = Resolve(networkObjectRef); + if (networkObject != null) + { + return networkObject.gameObject; + } + + return null; + } /// /// Implicitly convert to . diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs index 0884275276..07cd5769c7 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Serialization/NetworkObjectReferenceTests.cs @@ -25,12 +25,9 @@ private class TestNetworkBehaviour : NetworkBehaviour public GameObject RpcReceivedGameObject; - public bool ReceivedRpc; - [ServerRpc] public void SendReferenceServerRpc(NetworkObjectReference value) { - ReceivedRpc = true; RpcReceivedGameObject = value; RpcReceivedNetworkObject = value; }