diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 13f6126579..d3417214a5 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -15,6 +15,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- Fixed issue where `AnticipatedNetworkVariable` previous value returned by `AnticipatedNetworkVariable.OnAuthoritativeValueChanged` is updated correctly on the non-authoritative side. (#3306) - Fixed `OnClientConnectedCallback` passing incorrect `clientId` when scene management is disabled. (#3312) - Fixed issue where the `NetworkObject.Ownership` custom editor did not take the default "Everything" flag into consideration. (#3305) - Fixed DestroyObject flow on non-authority game clients. (#3291) diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs index d9d4e87393..94625722e3 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs @@ -387,6 +387,9 @@ public override void ReadField(FastBufferReader reader) public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta) { m_AuthoritativeValue.ReadDelta(reader, keepDirtyDelta); + // Assure that the post delta read is invoked in order to update + // previous value. + m_AuthoritativeValue.PostDeltaRead(); } } } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableAnticipationTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableAnticipationTests.cs index c436275fea..66d2d8d90f 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableAnticipationTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariable/NetworkVariableAnticipationTests.cs @@ -416,5 +416,39 @@ public void WhenStaleDataArrivesToReanticipatedVariable_ItIsAppliedAndReanticipa Assert.AreEqual(25, otherClientComponent.ReanticipateOnAnticipationFailVariable.Value); Assert.AreEqual(20, otherClientComponent.ReanticipateOnAnticipationFailVariable.AuthoritativeValue); } + + + private int m_PreviousSnapValue; + /// + /// Validates the previous value is being properly updated on the non-authoritative side. + /// + [Test] + public void PreviousValueIsMaintainedProperly() + { + var testComponent = GetTestComponent(); + + testComponent.SnapOnAnticipationFailVariable.OnAuthoritativeValueChanged += OnAuthoritativeValueChanged; + testComponent.SnapOnAnticipationFailVariable.Anticipate(10); + testComponent.SetSnapValueRpc(10); + WaitForMessageReceivedWithTimeTravel(m_ClientNetworkManagers.ToList()); + // Verify the previous value is 0 + Assert.AreEqual(0, m_PreviousSnapValue); + testComponent.SetSnapValueRpc(20); + + WaitForMessageReceivedWithTimeTravel(m_ClientNetworkManagers.ToList()); + // Verify the previous value is 10 + Assert.AreEqual(10, m_PreviousSnapValue); + + testComponent.SetSnapValueRpc(30); + WaitForMessageReceivedWithTimeTravel(m_ClientNetworkManagers.ToList()); + // Verify the previous value is 20 + Assert.AreEqual(20, m_PreviousSnapValue); + } + + private void OnAuthoritativeValueChanged(AnticipatedNetworkVariable anticipatedValue, in int previous, in int current) + { + m_PreviousSnapValue = previous; + } + } }