Skip to content

Commit cda389d

Browse files
authored
fix: Fixed NetworkVar assignment of the same value triggering replication (#1819)
1 parent c7e7584 commit cda389d

File tree

4 files changed

+70
-0
lines changed

4 files changed

+70
-0
lines changed

com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariable.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using UnityEngine;
22
using System;
3+
using System.Runtime.CompilerServices;
4+
using Unity.Collections.LowLevel.Unsafe;
35

46
namespace Unity.Netcode
57
{
@@ -87,6 +89,12 @@ public virtual T Value
8789
get => m_InternalValue;
8890
set
8991
{
92+
// Compare bitwise
93+
if (ValueEquals(ref m_InternalValue, ref value))
94+
{
95+
return;
96+
}
97+
9098
if (m_NetworkBehaviour && !CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId))
9199
{
92100
throw new InvalidOperationException("Client is not allowed to write to this NetworkVariable");
@@ -96,6 +104,21 @@ public virtual T Value
96104
}
97105
}
98106

107+
// Compares two values of the same unmanaged type by underlying memory
108+
// Ignoring any overriden value checks
109+
// Size is fixed
110+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
111+
private static unsafe bool ValueEquals(ref T a, ref T b)
112+
{
113+
// get unmanaged pointers
114+
var aptr = UnsafeUtility.AddressOf(ref a);
115+
var bptr = UnsafeUtility.AddressOf(ref b);
116+
117+
// compare addresses
118+
return UnsafeUtility.MemCmp(aptr, bptr, sizeof(T)) == 0;
119+
}
120+
121+
99122
private protected void Set(T value)
100123
{
101124
m_IsDirty = true;

com.unity.netcode.gameobjects/Tests/Editor/NetworkVar.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using NUnit.Framework;
2+
3+
namespace Unity.Netcode.EditorTests.NetworkVar
4+
{
5+
public class NetworkVarTests
6+
{
7+
[Test]
8+
public void TestAssignmentUnchanged()
9+
{
10+
var intVar = new NetworkVariable<int>();
11+
12+
intVar.Value = 314159265;
13+
14+
intVar.OnValueChanged += (value, newValue) =>
15+
{
16+
Assert.Fail("OnValueChanged was invoked when setting the same value");
17+
};
18+
19+
intVar.Value = 314159265;
20+
}
21+
22+
[Test]
23+
public void TestAssignmentChanged()
24+
{
25+
var intVar = new NetworkVariable<int>();
26+
27+
intVar.Value = 314159265;
28+
29+
var changed = false;
30+
31+
intVar.OnValueChanged += (value, newValue) =>
32+
{
33+
changed = true;
34+
};
35+
36+
intVar.Value = 314159266;
37+
38+
Assert.True(changed);
39+
}
40+
}
41+
}

com.unity.netcode.gameobjects/Tests/Editor/NetworkVar/NetworkVarTests.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)