Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Additional documentation and release notes are available at [Multiplayer Documen

- When using `UnityTransport`, _reliable_ payloads are now allowed to exceed the configured 'Max Payload Size'. Unreliable payloads remain bounded by this setting. (#2081)

- Preformance improvements for cases with large number of NetworkObjects, by not iterating over all unchanged NetworkObjects
Comment thread
NoelStephensUnity marked this conversation as resolved.

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@ internal void PostNetworkVariableWrite()
{
NetworkVariableFields[NetworkVariableIndexesToReset[i]].ResetDirty();
}

MarkVariablesDirty(false);
}

internal void VariableUpdate(ulong targetClientId)
Expand Down Expand Up @@ -664,11 +666,11 @@ private bool CouldHaveDirtyNetworkVariables()
return false;
}

internal void MarkVariablesDirty()
internal void MarkVariablesDirty(bool dirty)
{
for (int j = 0; j < NetworkVariableFields.Count; j++)
{
NetworkVariableFields[j].SetDirty(true);
NetworkVariableFields[j].SetDirty(dirty);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ namespace Unity.Netcode
/// </summary>
public class NetworkBehaviourUpdater
{
private HashSet<NetworkObject> m_Touched = new HashSet<NetworkObject>();
private HashSet<NetworkObject> m_DirtyNetworkObjects = new HashSet<NetworkObject>();
Comment thread
jeffreyrainy marked this conversation as resolved.

#if DEVELOPMENT_BUILD || UNITY_EDITOR
private ProfilerMarker m_NetworkBehaviourUpdate = new ProfilerMarker($"{nameof(NetworkBehaviour)}.{nameof(NetworkBehaviourUpdate)}");
#endif

internal void AddForUpdate(NetworkObject networkObject)
{
m_DirtyNetworkObjects.Add(networkObject);
}

internal void NetworkBehaviourUpdate(NetworkManager networkManager)
{
#if DEVELOPMENT_BUILD || UNITY_EDITOR
Expand All @@ -23,38 +28,31 @@ internal void NetworkBehaviourUpdate(NetworkManager networkManager)
{
if (networkManager.IsServer)
{
m_Touched.Clear();
for (int i = 0; i < networkManager.ConnectedClientsList.Count; i++)
foreach (var dirtyObj in m_DirtyNetworkObjects)
{
var client = networkManager.ConnectedClientsList[i];
var spawnedObjs = networkManager.SpawnManager.SpawnedObjectsList;
m_Touched.UnionWith(spawnedObjs);
foreach (var sobj in spawnedObjs)
for (int i = 0; i < networkManager.ConnectedClientsList.Count; i++)
{
if (sobj.IsNetworkVisibleTo(client.ClientId))
var client = networkManager.ConnectedClientsList[i];
if (networkManager.IsHost && client.ClientId == networkManager.LocalClientId)
{
continue;
}

if (dirtyObj.IsNetworkVisibleTo(client.ClientId))
{
// Sync just the variables for just the objects this client sees
for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++)
for (int k = 0; k < dirtyObj.ChildNetworkBehaviours.Count; k++)
{
sobj.ChildNetworkBehaviours[k].VariableUpdate(client.ClientId);
dirtyObj.ChildNetworkBehaviours[k].VariableUpdate(client.ClientId);
}
}
}
}

// Now, reset all the no-longer-dirty variables
foreach (var sobj in m_Touched)
{
for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++)
{
sobj.ChildNetworkBehaviours[k].PostNetworkVariableWrite();
}
}
}
else
{
// when client updates the server, it tells it about all its objects
foreach (var sobj in networkManager.SpawnManager.SpawnedObjectsList)
foreach (var sobj in m_DirtyNetworkObjects)
{
if (sobj.IsOwner)
{
Expand All @@ -64,16 +62,16 @@ internal void NetworkBehaviourUpdate(NetworkManager networkManager)
}
}
}

// Now, reset all the no-longer-dirty variables
foreach (var sobj in networkManager.SpawnManager.SpawnedObjectsList)
}
// Now, reset all the no-longer-dirty variables
foreach (var dirtyobj in m_DirtyNetworkObjects)
{
for (int k = 0; k < dirtyobj.ChildNetworkBehaviours.Count; k++)
{
for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++)
{
sobj.ChildNetworkBehaviours[k].PostNetworkVariableWrite();
}
dirtyobj.ChildNetworkBehaviours[k].PostNetworkVariableWrite();
}
}
m_DirtyNetworkObjects.Clear();
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ internal static string PrefabDebugHelper(NetworkPrefab networkPrefab)
return $"{nameof(NetworkPrefab)} \"{networkPrefab.Prefab.gameObject.name}\"";
}

internal NetworkBehaviourUpdater BehaviourUpdater { get; private set; }
internal NetworkBehaviourUpdater BehaviourUpdater { get; set; }

internal void MarkNetworkObjectDirty(NetworkObject networkObject)
{
BehaviourUpdater.AddForUpdate(networkObject);
}

internal MessagingSystem MessagingSystem { get; private set; }

Expand Down
4 changes: 2 additions & 2 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -868,12 +868,12 @@ internal void WriteNetworkVariableData(FastBufferWriter writer, ulong targetClie
}
}

internal void MarkVariablesDirty()
internal void MarkVariablesDirty(bool dirty)
{
for (int i = 0; i < ChildNetworkBehaviours.Count; i++)
{
var behavior = ChildNetworkBehaviours[i];
behavior.MarkVariablesDirty();
behavior.MarkVariablesDirty(dirty);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ public override bool IsDirty()
return base.IsDirty() || m_DirtyEvents.Length > 0;
}

internal void MarkNetworkObjectDirty()
{
m_NetworkBehaviour.NetworkManager.MarkNetworkObjectDirty(m_NetworkBehaviour.NetworkObject);
}

/// <inheritdoc />
public override void WriteDelta(FastBufferWriter writer)
{
Expand Down Expand Up @@ -189,6 +194,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
Index = m_List.Length - 1,
Value = m_List[m_List.Length - 1]
});
MarkNetworkObjectDirty();
}
}
break;
Expand Down Expand Up @@ -225,6 +231,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
Index = index,
Value = m_List[index]
});
MarkNetworkObjectDirty();
}
}
break;
Expand Down Expand Up @@ -257,6 +264,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
Index = index,
Value = value
});
MarkNetworkObjectDirty();
}
}
break;
Expand Down Expand Up @@ -284,6 +292,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
Index = index,
Value = value
});
MarkNetworkObjectDirty();
}
}
break;
Expand Down Expand Up @@ -319,6 +328,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
Value = value,
PreviousValue = previousValue
});
MarkNetworkObjectDirty();
}
}
break;
Expand All @@ -341,6 +351,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
{
Type = eventType
});
MarkNetworkObjectDirty();
}
}
break;
Expand Down Expand Up @@ -485,6 +496,7 @@ public T this[int index]
private void HandleAddListEvent(NetworkListEvent<T> listEvent)
{
m_DirtyEvents.Add(listEvent);
MarkNetworkObjectDirty();
OnListChanged?.Invoke(listEvent);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private static unsafe bool ValueEquals(ref T a, ref T b)
/// <param name="value">the new value of type `T` to be set/></param>
private protected void Set(T value)
{
m_IsDirty = true;
SetDirty(true);
T previousValue = m_InternalValue;
m_InternalValue = value;
OnValueChanged?.Invoke(previousValue, m_InternalValue);
Expand Down Expand Up @@ -119,7 +119,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)

if (keepDirtyDelta)
{
m_IsDirty = true;
SetDirty(true);
}

OnValueChanged?.Invoke(previousValue, m_InternalValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected NetworkVariableBase(
/// The <see cref="m_IsDirty"/> property is used to determine if the
/// value of the `NetworkVariable` has changed.
/// </summary>
private protected bool m_IsDirty;
private bool m_IsDirty;

/// <summary>
/// Gets or sets the name of the network variable's instance
Expand All @@ -79,6 +79,10 @@ protected NetworkVariableBase(
public virtual void SetDirty(bool isDirty)
{
m_IsDirty = isDirty;
Comment thread
jeffreyrainy marked this conversation as resolved.
if (m_IsDirty)
{
m_NetworkBehaviour.NetworkManager.MarkNetworkObjectDirty(m_NetworkBehaviour.NetworkObject);
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ internal void SendSpawnCallForObject(ulong clientId, NetworkObject networkObject
var size = NetworkManager.SendMessage(ref message, NetworkDelivery.ReliableFragmentedSequenced, clientId);
NetworkManager.NetworkMetrics.TrackObjectSpawnSent(clientId, networkObject, size);

networkObject.MarkVariablesDirty();
networkObject.MarkVariablesDirty(true);
}

internal ulong? GetSpawnParentId(NetworkObject networkObject)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,55 @@
using NUnit.Framework;
using UnityEngine;

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

intVar.Value = 314159265;

intVar.OnValueChanged += (value, newValue) =>
var gameObjectMan = new GameObject();
var networkManager = gameObjectMan.AddComponent<NetworkManager>();
networkManager.BehaviourUpdater = new NetworkBehaviourUpdater();
var gameObject = new GameObject();
var networkObject = gameObject.AddComponent<NetworkObject>();
networkObject.NetworkManagerOwner = networkManager;
var networkVarComponent = gameObject.AddComponent<NetworkVarComponent>();
networkVarComponent.NetworkVariable.Initialize(networkVarComponent);
networkVarComponent.NetworkVariable.Value = 314159265;
networkVarComponent.NetworkVariable.OnValueChanged += (value, newValue) =>
{
Assert.Fail("OnValueChanged was invoked when setting the same value");
};

intVar.Value = 314159265;
networkVarComponent.NetworkVariable.Value = 314159265;
Object.DestroyImmediate(gameObject);
Object.DestroyImmediate(gameObjectMan);
}

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

intVar.Value = 314159265;

var gameObjectMan = new GameObject();
var networkManager = gameObjectMan.AddComponent<NetworkManager>();
networkManager.BehaviourUpdater = new NetworkBehaviourUpdater();
var gameObject = new GameObject();
var networkObject = gameObject.AddComponent<NetworkObject>();
var networkVarComponent = gameObject.AddComponent<NetworkVarComponent>();
networkObject.NetworkManagerOwner = networkManager;
networkVarComponent.NetworkVariable.Initialize(networkVarComponent);
networkVarComponent.NetworkVariable.Value = 314159265;
var changed = false;

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

intVar.Value = 314159266;

networkVarComponent.NetworkVariable.Value = 314159266;
Assert.True(changed);
Object.DestroyImmediate(gameObject);
Object.DestroyImmediate(gameObjectMan);
}
}
}
Loading