Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ namespace Unity.Netcode
{
public class NetworkBehaviourUpdater
{
private HashSet<NetworkObject> m_Touched = new HashSet<NetworkObject>();
private HashSet<NetworkObject> m_DirtyNetworkObjects = new HashSet<NetworkObject>();

#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 @@ -20,38 +25,42 @@ 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)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this safe? The perf benefit is negligible and there's stuff happening in PreNetworkVariableWrite(), but I haven't dug really deep into what it's doing.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just skipping the update for the host client since it will already be applied locally.

{
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)
foreach (var dirtyObj in m_DirtyNetworkObjects)
{
for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++)
for (int k = 0; k < dirtyObj.ChildNetworkBehaviours.Count; k++)
{
sobj.ChildNetworkBehaviours[k].PostNetworkVariableWrite();
dirtyObj.ChildNetworkBehaviours[k].PostNetworkVariableWrite();
}
}
m_DirtyNetworkObjects.Clear();
}
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 @@ -63,13 +72,14 @@ internal void NetworkBehaviourUpdate(NetworkManager networkManager)
}

// Now, reset all the no-longer-dirty variables
foreach (var sobj in networkManager.SpawnManager.SpawnedObjectsList)
foreach (var sobj in m_DirtyNetworkObjects)
{
for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++)
{
sobj.ChildNetworkBehaviours[k].PostNetworkVariableWrite();
}
}
m_DirtyNetworkObjects.Clear();
}
}
finally
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ internal static string PrefabDebugHelper(NetworkPrefab networkPrefab)

internal NetworkBehaviourUpdater BehaviourUpdater { get; private set; }

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

internal MessagingSystem MessagingSystem { get; private set; }

private NetworkPrefabHandler m_PrefabHandler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private static unsafe bool ValueEquals(ref T a, ref T b)

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 @@ -106,7 +106,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 @@ -30,7 +30,7 @@ protected NetworkVariableBase(
WritePerm = writePerm;
}

private protected bool m_IsDirty;
private bool m_IsDirty;

/// <summary>
/// Gets or sets the name of the network variable's instance
Expand All @@ -51,6 +51,7 @@ protected NetworkVariableBase(
public virtual void SetDirty(bool isDirty)
{
m_IsDirty = isDirty;
m_NetworkBehaviour.NetworkManager.MarkNetworkObjectDirty(m_NetworkBehaviour.NetworkObject);
Copy link
Copy Markdown

@davidvogelunity davidvogelunity Jun 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In testing on my project, it's possible for this to be null, likely this gets called before Initialize(). Probably worth checking for dirty in Initialize() too.

While there aren't any cases with false now, it might be worth checking too.

}

/// <summary>
Expand Down