Skip to content

Commit ea046c5

Browse files
fix: NetworkVariables with NetworkVariableUpdateTraits can cause other NetworkVariables to drop changes (#3465)
This PR resolves an issue where a `NetworkBehaviour` with multiple `NetworkVariables` could drop changes if one of the `NetworkVariables` has unique `NetworkVariableUpdateTraits` set, is dirty, but is not ready to send. Based on user @khyperia's submission #3462. ## Changelog - 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. ## Testing and Documentation - Includes integration test `NetworkVariableTraitsTests.WhenNonTraitsIsDirtyButTraitsIsNotReadyToSend`. - No documentation changes or additions were necessary. <!-- Uncomment and mark items off with a * if this PR deprecates any API: ### Deprecated API - [ ] An `[Obsolete]` attribute was added along with a `(RemovedAfter yyyy-mm-dd)` entry. - [ ] An [api updater] was added. - [ ] Deprecation of the API is explained in the CHANGELOG. - [ ] The users can understand why this API was removed and what they should use instead. --> ## Backport This required and up-port to v2.x (#3466) --------- Co-authored-by: khyperia <953151+khyperia@users.noreply.github.com>
1 parent 11dcd06 commit ea046c5

File tree

3 files changed

+55
-17
lines changed

3 files changed

+55
-17
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1414

1515
### Fixed
1616

17+
- 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)
1718
- Fixed issue where when a client changes ownership via RPC the `NetworkBehaviour.OnOwnershipChanged` can result in identical previous and current owner identifiers. (#3434)
1819

1920
### Changed

com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1002,8 +1002,8 @@ internal void NetworkVariableUpdate(ulong targetClientId, int behaviourIndex, bo
10021002
if (networkVariable.CanSend())
10031003
{
10041004
shouldSend = true;
1005+
break;
10051006
}
1006-
break;
10071007
}
10081008
}
10091009

com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTraitsTests.cs

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace Unity.Netcode.RuntimeTests
88
public class NetworkVariableTraitsComponent : NetworkBehaviour
99
{
1010
public NetworkVariable<float> TheVariable = new NetworkVariable<float>();
11+
internal NetworkVariable<float> AnotherVariable = new NetworkVariable<float>();
1112
}
1213

1314
public class NetworkVariableTraitsTests : NetcodeIntegrationTest
@@ -52,9 +53,10 @@ public void WhenNewValueIsLessThanThreshold_VariableIsNotSerialized()
5253

5354
TimeTravel(2, 120);
5455

55-
Assert.AreEqual(0.05f, serverComponent.TheVariable.Value); ;
56-
Assert.AreEqual(0, testComponent.TheVariable.Value); ;
56+
Assert.AreEqual(0.05f, serverComponent.TheVariable.Value);
57+
Assert.AreEqual(0, testComponent.TheVariable.Value);
5758
}
59+
5860
[Test]
5961
public void WhenNewValueIsGreaterThanThreshold_VariableIsSerialized()
6062
{
@@ -66,8 +68,8 @@ public void WhenNewValueIsGreaterThanThreshold_VariableIsSerialized()
6668

6769
TimeTravel(2, 120);
6870

69-
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); ;
70-
Assert.AreEqual(0.15f, testComponent.TheVariable.Value); ;
71+
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value);
72+
Assert.AreEqual(0.15f, testComponent.TheVariable.Value);
7173
}
7274

7375
[Test]
@@ -83,13 +85,13 @@ public void WhenNewValueIsLessThanThresholdButMaxTimeHasPassed_VariableIsSeriali
8385

8486
TimeTravel(1 / 60f * 119, 119);
8587

86-
Assert.AreEqual(0.05f, serverComponent.TheVariable.Value); ;
87-
Assert.AreEqual(0, testComponent.TheVariable.Value); ;
88+
Assert.AreEqual(0.05f, serverComponent.TheVariable.Value);
89+
Assert.AreEqual(0, testComponent.TheVariable.Value);
8890

8991
TimeTravel(1 / 60f * 4, 4);
9092

91-
Assert.AreEqual(0.05f, serverComponent.TheVariable.Value); ;
92-
Assert.AreEqual(0.05f, testComponent.TheVariable.Value); ;
93+
Assert.AreEqual(0.05f, serverComponent.TheVariable.Value);
94+
Assert.AreEqual(0.05f, testComponent.TheVariable.Value);
9395
}
9496

9597
[Test]
@@ -105,13 +107,13 @@ public void WhenNewValueIsGreaterThanThresholdButMinTimeHasNotPassed_VariableIsN
105107

106108
TimeTravel(1 / 60f * 119, 119);
107109

108-
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); ;
109-
Assert.AreEqual(0, testComponent.TheVariable.Value); ;
110+
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value);
111+
Assert.AreEqual(0, testComponent.TheVariable.Value);
110112

111113
TimeTravel(1 / 60f * 4, 4);
112114

113-
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); ;
114-
Assert.AreEqual(0.15f, testComponent.TheVariable.Value); ;
115+
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value);
116+
Assert.AreEqual(0.15f, testComponent.TheVariable.Value);
115117
}
116118

117119
[Test]
@@ -126,13 +128,48 @@ public void WhenNoThresholdIsSetButMinTimeHasNotPassed_VariableIsNotSerialized()
126128

127129
TimeTravel(1 / 60f * 119, 119);
128130

129-
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); ;
130-
Assert.AreEqual(0, testComponent.TheVariable.Value); ;
131+
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value);
132+
Assert.AreEqual(0, testComponent.TheVariable.Value);
133+
134+
TimeTravel(1 / 60f * 4, 4);
135+
136+
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value);
137+
Assert.AreEqual(0.15f, testComponent.TheVariable.Value);
138+
}
131139

140+
/// <summary>
141+
/// Integration test to validate that a <see cref="NetworkVariable{T}"/> with <see cref="NetworkVariableUpdateTraits"/>
142+
/// does not cause other <see cref="NetworkVariable{T}"/>s to miss an update when they are dirty but the one with
143+
/// traits is not ready to send an update.
144+
/// </summary>
145+
[Test]
146+
public void WhenNonTraitsIsDirtyButTraitsIsNotReadyToSend()
147+
{
148+
var serverComponent = GetServerComponent();
149+
var testComponent = GetTestComponent();
150+
serverComponent.TheVariable.SetUpdateTraits(new NetworkVariableUpdateTraits { MinSecondsBetweenUpdates = 2 });
151+
serverComponent.TheVariable.LastUpdateSent = m_ServerNetworkManager.NetworkTimeSystem.LocalTime;
152+
153+
serverComponent.TheVariable.Value = 0.15f;
154+
// Set the non-traits NetworkVariable value
155+
serverComponent.AnotherVariable.Value = 1.0f;
156+
157+
TimeTravel(1 / 60f * 119, 119);
158+
// We don't expect the traits NetworkVariable to update
159+
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value);
160+
Assert.AreEqual(0, testComponent.TheVariable.Value);
161+
// We should expect the non-traits NetworkVariable to update
162+
Assert.AreEqual(1.0f, serverComponent.AnotherVariable.Value);
163+
Assert.AreEqual(1.0f, testComponent.AnotherVariable.Value);
164+
165+
serverComponent.AnotherVariable.Value = 1.5f;
132166
TimeTravel(1 / 60f * 4, 4);
133167

134-
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value); ;
135-
Assert.AreEqual(0.15f, testComponent.TheVariable.Value); ;
168+
// We should expect both NetworkVariables to update
169+
Assert.AreEqual(0.15f, serverComponent.TheVariable.Value);
170+
Assert.AreEqual(0.15f, testComponent.TheVariable.Value);
171+
Assert.AreEqual(1.5f, serverComponent.AnotherVariable.Value);
172+
Assert.AreEqual(1.5f, testComponent.AnotherVariable.Value);
136173
}
137174
}
138175
}

0 commit comments

Comments
 (0)