Skip to content

fix: Fixed NetworkVar assignment of the same value triggering replication #1819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 23, 2022
Merged
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using UnityEngine;
using System;
using System.Runtime.CompilerServices;
using Unity.Collections.LowLevel.Unsafe;

namespace Unity.Netcode
{
Expand Down Expand Up @@ -87,6 +89,12 @@ public virtual T Value
get => m_InternalValue;
set
{
// Compare bitwise
if (ValueEquals(ref m_InternalValue, ref value))
{
return;
}

if (m_NetworkBehaviour && !CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId))
{
throw new InvalidOperationException("Client is not allowed to write to this NetworkVariable");
Expand All @@ -96,6 +104,21 @@ public virtual T Value
}
}

// Compares two values of the same unmanaged type by underlying memory
// Ignoring any overriden value checks
// Size is fixed
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe bool ValueEquals(ref T a, ref T b)
{
// get unmanaged pointers
var aptr = UnsafeUtility.AddressOf(ref a);
var bptr = UnsafeUtility.AddressOf(ref b);

// compare addresses
return UnsafeUtility.MemCmp(aptr, bptr, sizeof(T)) == 0;
}


private protected void Set(T value)
{
m_IsDirty = true;
Expand Down
3 changes: 3 additions & 0 deletions com.unity.netcode.gameobjects/Tests/Editor/NetworkVar.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using NUnit.Framework;

namespace Unity.Netcode.EditorTests.NetworkVar
{
public class NetworkVarTests
{
[Test]
public void TestAssignmentUnchanged()
{
var intVar = new NetworkVariable<int>();

intVar.Value = 314159265;

intVar.OnValueChanged += (value, newValue) =>
{
Assert.Fail("OnValueChanged was invoked when setting the same value");
};

intVar.Value = 314159265;
}

[Test]
public void TestAssignmentChanged()
{
var intVar = new NetworkVariable<int>();

intVar.Value = 314159265;

var changed = false;

intVar.OnValueChanged += (value, newValue) =>
{
changed = true;
};

intVar.Value = 314159266;

Assert.True(changed);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.