From d01003baee0b69281a25beb8315180dcda4df6d0 Mon Sep 17 00:00:00 2001 From: khyperia <953151+khyperia@users.noreply.github.com> Date: Wed, 28 May 2025 12:26:09 +0200 Subject: [PATCH 1/6] Fix NetworkVariables sometimes dropping changes --- com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index a1e0278369..f534351a1b 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -1002,8 +1002,8 @@ internal void NetworkVariableUpdate(ulong targetClientId, int behaviourIndex, bo if (networkVariable.CanSend()) { shouldSend = true; + break; } - break; } } From df80baccc9f747e73071b8f48e206a444f37fb58 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Wed, 28 May 2025 13:16:17 -0500 Subject: [PATCH 2/6] update adding change log entry. --- 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 33da2cb693..af133c3c5c 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -14,6 +14,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- Fixed issue where `NetworkVariable`s on a `NetworkBehaviour` could fail to synchronize changes if one is dirty but not ready to send. (#3465) - Fixed issue where when a client changes ownership via RPC the `NetworkBehaviour.OnOwnershipChanged` can result in identical previous and current owner identifiers. (#3434) ### Changed From a2798908391f7d2dbb806273839f735336b1a3cd Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Wed, 28 May 2025 13:50:30 -0500 Subject: [PATCH 3/6] test Adding test to verify this fix. --- .../Runtime/NetworkVariableTraitsTests.cs | 64 ++++++++++++++----- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs index 1c3872ac3a..840cde1297 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs @@ -8,6 +8,7 @@ namespace Unity.Netcode.RuntimeTests public class NetworkVariableTraitsComponent : NetworkBehaviour { public NetworkVariable TheVariable = new NetworkVariable(); + public NetworkVariable AnotherVariable = new NetworkVariable(); } public class NetworkVariableTraitsTests : NetcodeIntegrationTest @@ -52,9 +53,10 @@ public void WhenNewValueIsLessThanThreshold_VariableIsNotSerialized() TimeTravel(2, 120); - Assert.AreEqual(0.05f, serverComponent.TheVariable.Value); ; - Assert.AreEqual(0, testComponent.TheVariable.Value); ; + Assert.AreEqual(0.05f, serverComponent.TheVariable.Value); + Assert.AreEqual(0, testComponent.TheVariable.Value); } + [Test] public void WhenNewValueIsGreaterThanThreshold_VariableIsSerialized() { @@ -66,8 +68,8 @@ public void WhenNewValueIsGreaterThanThreshold_VariableIsSerialized() TimeTravel(2, 120); - Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); ; - Assert.AreEqual(0.15f, testComponent.TheVariable.Value); ; + Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); + Assert.AreEqual(0.15f, testComponent.TheVariable.Value); } [Test] @@ -83,13 +85,13 @@ public void WhenNewValueIsLessThanThresholdButMaxTimeHasPassed_VariableIsSeriali TimeTravel(1 / 60f * 119, 119); - Assert.AreEqual(0.05f, serverComponent.TheVariable.Value); ; - Assert.AreEqual(0, testComponent.TheVariable.Value); ; + Assert.AreEqual(0.05f, serverComponent.TheVariable.Value); + Assert.AreEqual(0, testComponent.TheVariable.Value); TimeTravel(1 / 60f * 4, 4); - Assert.AreEqual(0.05f, serverComponent.TheVariable.Value); ; - Assert.AreEqual(0.05f, testComponent.TheVariable.Value); ; + Assert.AreEqual(0.05f, serverComponent.TheVariable.Value); + Assert.AreEqual(0.05f, testComponent.TheVariable.Value); } [Test] @@ -105,13 +107,13 @@ public void WhenNewValueIsGreaterThanThresholdButMinTimeHasNotPassed_VariableIsN TimeTravel(1 / 60f * 119, 119); - Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); ; - Assert.AreEqual(0, testComponent.TheVariable.Value); ; + Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); + Assert.AreEqual(0, testComponent.TheVariable.Value); TimeTravel(1 / 60f * 4, 4); - Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); ; - Assert.AreEqual(0.15f, testComponent.TheVariable.Value); ; + Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); + Assert.AreEqual(0.15f, testComponent.TheVariable.Value); } [Test] @@ -126,13 +128,43 @@ public void WhenNoThresholdIsSetButMinTimeHasNotPassed_VariableIsNotSerialized() TimeTravel(1 / 60f * 119, 119); - Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); ; - Assert.AreEqual(0, testComponent.TheVariable.Value); ; + Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); + Assert.AreEqual(0, testComponent.TheVariable.Value); + + TimeTravel(1 / 60f * 4, 4); + + Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); + Assert.AreEqual(0.15f, testComponent.TheVariable.Value); + } + [Test] + public void WhenNonTraitsIsDirtyButTraitsIsNotReadyToSend() + { + var serverComponent = GetServerComponent(); + var testComponent = GetTestComponent(); + serverComponent.TheVariable.SetUpdateTraits(new NetworkVariableUpdateTraits { MinSecondsBetweenUpdates = 2 }); + serverComponent.TheVariable.LastUpdateSent = m_ServerNetworkManager.NetworkTimeSystem.LocalTime; + + serverComponent.TheVariable.Value = 0.15f; + // Set the non-traits NetworkVariable value + serverComponent.AnotherVariable.Value = 1.0f; + + TimeTravel(1 / 60f * 119, 119); + // We don't expect the traits NetworkVariable to update + Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); + Assert.AreEqual(0, testComponent.TheVariable.Value); + // We should expect the non-traits NetworkVariable to update + Assert.AreEqual(1.0f, serverComponent.AnotherVariable.Value); + Assert.AreEqual(1.0f, testComponent.AnotherVariable.Value); + + serverComponent.AnotherVariable.Value = 1.5f; TimeTravel(1 / 60f * 4, 4); - Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); ; - Assert.AreEqual(0.15f, testComponent.TheVariable.Value); ; + // We should expect both NetworkVariables to update + Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); + Assert.AreEqual(0.15f, testComponent.TheVariable.Value); + Assert.AreEqual(1.5f, serverComponent.AnotherVariable.Value); + Assert.AreEqual(1.5f, testComponent.AnotherVariable.Value); } } } From eeb6f73909c59014248f8e061263e18a2254c7c0 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Wed, 28 May 2025 13:50:53 -0500 Subject: [PATCH 4/6] update Adjusting changelog entry. --- com.unity.netcode.gameobjects/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index af133c3c5c..b96f523884 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -14,7 +14,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed -- Fixed issue where `NetworkVariable`s on a `NetworkBehaviour` could fail to synchronize changes if one is dirty but not ready to send. (#3465) +- Fixed issue where `NetworkVariable`s on a `NetworkBehaviour` could fail to synchronize changes if one has `NetworkVariableUpdateTraits` set and is dirty but is not ready to send. (#3465) - Fixed issue where when a client changes ownership via RPC the `NetworkBehaviour.OnOwnershipChanged` can result in identical previous and current owner identifiers. (#3434) ### Changed From de28f0d5944c2d1d1dc547a470eef62bb18a6948 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Wed, 28 May 2025 13:57:29 -0500 Subject: [PATCH 5/6] update - PVP Adding XML API to avoid PVP error. --- .../Tests/Runtime/NetworkVariableTraitsTests.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs index 840cde1297..080bdc9ad1 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs @@ -137,6 +137,11 @@ public void WhenNoThresholdIsSetButMinTimeHasNotPassed_VariableIsNotSerialized() Assert.AreEqual(0.15f, testComponent.TheVariable.Value); } + /// + /// Integration test to validate that a with + /// does not cause other s to miss an update when they are dirty but the one with + /// traits is not ready to send an update. + /// [Test] public void WhenNonTraitsIsDirtyButTraitsIsNotReadyToSend() { From 1d00d7c4a03c7f853cccd344c10a4cf28db95833 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Wed, 28 May 2025 14:01:01 -0500 Subject: [PATCH 6/6] update - PVP One more area that needed adjusting to avoid PVP error. --- .../Tests/Runtime/NetworkVariableTraitsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs index 080bdc9ad1..eb9b9589d2 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs @@ -8,7 +8,7 @@ namespace Unity.Netcode.RuntimeTests public class NetworkVariableTraitsComponent : NetworkBehaviour { public NetworkVariable TheVariable = new NetworkVariable(); - public NetworkVariable AnotherVariable = new NetworkVariable(); + internal NetworkVariable AnotherVariable = new NetworkVariable(); } public class NetworkVariableTraitsTests : NetcodeIntegrationTest