Skip to content

Commit 214fb26

Browse files
Improving performance of BehaviourUpdater
- Full credit to Unity-Technologies#1951
1 parent 472d51b commit 214fb26

4 files changed

Lines changed: 34 additions & 41 deletions

File tree

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

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,14 @@ internal void InitializeVariables()
567567
}
568568
}
569569

570+
internal void MarkDirty()
571+
{
572+
if (m_NetworkObject != null)
573+
{
574+
NetworkManager.BehaviourUpdater.AddForUpdate(this);
575+
}
576+
}
577+
570578
internal void PreNetworkVariableWrite()
571579
{
572580
// reset our "which variables got written" data
@@ -599,11 +607,6 @@ internal void VariableUpdate(ulong targetClientId)
599607

600608
private void NetworkVariableUpdate(ulong targetClientId, int behaviourIndex)
601609
{
602-
if (!CouldHaveDirtyNetworkVariables())
603-
{
604-
return;
605-
}
606-
607610
for (int j = 0; j < m_DeliveryMappedNetworkVariableIndices.Count; j++)
608611
{
609612
var shouldSend = false;
@@ -648,20 +651,6 @@ private void NetworkVariableUpdate(ulong targetClientId, int behaviourIndex)
648651
}
649652
}
650653

651-
private bool CouldHaveDirtyNetworkVariables()
652-
{
653-
// TODO: There should be a better way by reading one dirty variable vs. 'n'
654-
for (int i = 0; i < NetworkVariableFields.Count; i++)
655-
{
656-
if (NetworkVariableFields[i].IsDirty())
657-
{
658-
return true;
659-
}
660-
}
661-
662-
return false;
663-
}
664-
665654
internal void MarkVariablesDirty()
666655
{
667656
for (int j = 0; j < NetworkVariableFields.Count; j++)

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

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@ namespace Unity.Netcode
55
{
66
public class NetworkBehaviourUpdater
77
{
8-
private HashSet<NetworkObject> m_Touched = new HashSet<NetworkObject>();
8+
private HashSet<NetworkBehaviour> m_Touched = new HashSet<NetworkBehaviour>();
99

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

14+
internal void AddForUpdate(NetworkBehaviour networkBehaviour)
15+
{
16+
m_Touched.Add(networkBehaviour);
17+
}
18+
1419
internal void NetworkBehaviourUpdate(NetworkManager networkManager)
1520
{
1621
#if DEVELOPMENT_BUILD || UNITY_EDITOR
@@ -20,33 +25,24 @@ internal void NetworkBehaviourUpdate(NetworkManager networkManager)
2025
{
2126
if (networkManager.IsServer)
2227
{
23-
m_Touched.Clear();
24-
for (int i = 0; i < networkManager.ConnectedClientsList.Count; i++)
28+
foreach (var networkBehaviour in m_Touched)
2529
{
26-
var client = networkManager.ConnectedClientsList[i];
27-
var spawnedObjs = networkManager.SpawnManager.SpawnedObjectsList;
28-
m_Touched.UnionWith(spawnedObjs);
29-
foreach (var sobj in spawnedObjs)
30+
foreach (var client in networkManager.ConnectedClientsList)
3031
{
31-
if (sobj.IsNetworkVisibleTo(client.ClientId))
32+
if (!networkBehaviour.HasNetworkObject || !networkBehaviour.NetworkObject.IsNetworkVisibleTo(client.ClientId))
3233
{
33-
// Sync just the variables for just the objects this client sees
34-
for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++)
35-
{
36-
sobj.ChildNetworkBehaviours[k].VariableUpdate(client.ClientId);
37-
}
34+
continue;
3835
}
36+
37+
networkBehaviour.VariableUpdate(client.ClientId);
3938
}
4039
}
4140

42-
// Now, reset all the no-longer-dirty variables
43-
foreach (var sobj in m_Touched)
41+
foreach (var networkBehaviour in m_Touched)
4442
{
45-
for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++)
46-
{
47-
sobj.ChildNetworkBehaviours[k].PostNetworkVariableWrite();
48-
}
43+
networkBehaviour.PostNetworkVariableWrite();
4944
}
45+
m_Touched.Clear();
5046
}
5147
else
5248
{

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ private static unsafe bool ValueEquals(ref T a, ref T b)
7474

7575
private protected void Set(T value)
7676
{
77-
m_IsDirty = true;
77+
SetDirty(true);
7878
T previousValue = m_InternalValue;
7979
m_InternalValue = value;
8080
OnValueChanged?.Invoke(previousValue, m_InternalValue);
@@ -106,7 +106,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
106106

107107
if (keepDirtyDelta)
108108
{
109-
m_IsDirty = true;
109+
SetDirty(true);
110110
}
111111

112112
OnValueChanged?.Invoke(previousValue, m_InternalValue);

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ public abstract class NetworkVariableBase : IDisposable
1717
public void Initialize(NetworkBehaviour networkBehaviour)
1818
{
1919
m_NetworkBehaviour = networkBehaviour;
20+
if (IsDirty() && m_NetworkBehaviour != null)
21+
{
22+
m_NetworkBehaviour.MarkDirty();
23+
}
2024
}
2125

2226
public const NetworkVariableReadPermission DefaultReadPerm = NetworkVariableReadPermission.Everyone;
@@ -30,7 +34,7 @@ protected NetworkVariableBase(
3034
WritePerm = writePerm;
3135
}
3236

33-
private protected bool m_IsDirty;
37+
private bool m_IsDirty;
3438

3539
/// <summary>
3640
/// Gets or sets the name of the network variable's instance
@@ -51,6 +55,10 @@ protected NetworkVariableBase(
5155
public virtual void SetDirty(bool isDirty)
5256
{
5357
m_IsDirty = isDirty;
58+
if (isDirty && m_NetworkBehaviour != null)
59+
{
60+
m_NetworkBehaviour.MarkDirty();
61+
}
5462
}
5563

5664
/// <summary>

0 commit comments

Comments
 (0)