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
29 changes: 25 additions & 4 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,15 @@ internal void VisibleOnNetworkSpawn()
{
Debug.LogException(e);
}

InitializeVariables();
if (IsServer)
{
// Since we just spawned the object and since user code might have modified their NetworkVariable, esp.
// NetworkList, we need to mark the object as free of updates.
// This should happen for all objects on the machine triggering the spawn.
PostNetworkVariableWrite(true);
}
}

internal void InternalOnNetworkDespawn()
Expand Down Expand Up @@ -622,12 +631,24 @@ internal void PreNetworkVariableWrite()
NetworkVariableIndexesToResetSet.Clear();
}

internal void PostNetworkVariableWrite()
internal void PostNetworkVariableWrite(bool forced = false)
{
// mark any variables we wrote as no longer dirty
for (int i = 0; i < NetworkVariableIndexesToReset.Count; i++)
if (forced)
{
// Mark every variable as no longer dirty. We just spawned the object and whatever the game code did
// during OnNetworkSpawn has been sent and needs to be cleared
for (int i = 0; i < NetworkVariableFields.Count; i++)
{
NetworkVariableFields[i].ResetDirty();
}
}
else
{
NetworkVariableFields[NetworkVariableIndexesToReset[i]].ResetDirty();
// mark any variables we wrote as no longer dirty
for (int i = 0; i < NetworkVariableIndexesToReset.Count; i++)
{
NetworkVariableFields[NetworkVariableIndexesToReset[i]].ResetDirty();
}
}

MarkVariablesDirty(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ internal void NetworkBehaviourUpdate(NetworkManager networkManager)
// Now, reset all the no-longer-dirty variables
foreach (var dirtyobj in m_DirtyNetworkObjects)
{
for (int k = 0; k < dirtyobj.ChildNetworkBehaviours.Count; k++)
{
dirtyobj.ChildNetworkBehaviours[k].PostNetworkVariableWrite();
}
dirtyobj.PostNetworkVariableWrite();
}
m_DirtyNetworkObjects.Clear();
}
Expand Down
8 changes: 8 additions & 0 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,14 @@ public unsafe void Deserialize(FastBufferReader reader)
}
}

internal void PostNetworkVariableWrite()
{
for (int k = 0; k < ChildNetworkBehaviours.Count; k++)
{
ChildNetworkBehaviours[k].PostNetworkVariableWrite();
}
}

internal SceneObject GetMessageSceneObject(ulong targetClientId)
{
var obj = new SceneObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ namespace Unity.Netcode
public class NetworkList<T> : NetworkVariableBase where T : unmanaged, IEquatable<T>
{
private NativeList<T> m_List = new NativeList<T>(64, Allocator.Persistent);
private NativeList<T> m_ListAtLastReset = new NativeList<T>(64, Allocator.Persistent);
Copy link
Copy Markdown
Collaborator

@ShadauxCat ShadauxCat Sep 7, 2022

Choose a reason for hiding this comment

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

Glad to see this not be needed anymore. Good work finding a better solution! 🥳 🎉

private NativeList<NetworkListEvent<T>> m_DirtyEvents = new NativeList<NetworkListEvent<T>>(64, Allocator.Persistent);

/// <summary>
Expand Down Expand Up @@ -53,7 +52,6 @@ public override void ResetDirty()
if (m_DirtyEvents.Length > 0)
{
m_DirtyEvents.Clear();
m_ListAtLastReset.CopyFrom(m_List.AsArray());
}
}

Expand Down Expand Up @@ -135,26 +133,10 @@ public override void WriteDelta(FastBufferWriter writer)
/// <inheritdoc />
public override void WriteField(FastBufferWriter writer)
{
// The listAtLastReset mechanism was put in place to deal with duplicate adds
// upon initial spawn. However, it causes issues with in-scene placed objects
// due to difference in spawn order. In order to address this, we pick the right
// list based on the type of object.
bool isSceneObject = m_NetworkBehaviour.NetworkObject.IsSceneObject != false;
if (isSceneObject)
writer.WriteValueSafe((ushort)m_List.Length);
for (int i = 0; i < m_List.Length; i++)
{
writer.WriteValueSafe((ushort)m_ListAtLastReset.Length);
for (int i = 0; i < m_ListAtLastReset.Length; i++)
{
NetworkVariableSerialization<T>.Write(writer, ref m_ListAtLastReset.ElementAt(i));
}
}
else
{
writer.WriteValueSafe((ushort)m_List.Length);
for (int i = 0; i < m_List.Length; i++)
{
NetworkVariableSerialization<T>.Write(writer, ref m_List.ElementAt(i));
}
NetworkVariableSerialization<T>.Write(writer, ref m_List.ElementAt(i));
}
}

Expand Down Expand Up @@ -528,7 +510,6 @@ public int LastModifiedTick
public override void Dispose()
{
m_List.Dispose();
m_ListAtLastReset.Dispose();
m_DirtyEvents.Dispose();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ public override void OnNetworkSpawn()
{
ClientTargetedNetworkObjects.Add(this);
}

if (IsServer)
{
MyListSetOnSpawn.Add(45);
}
else
{
Debug.Assert(MyListSetOnSpawn.Count == 1);
Debug.Assert(MyListSetOnSpawn[0] == 45);
}

base.OnNetworkSpawn();
}

Expand All @@ -50,11 +61,14 @@ public override void OnNetworkDespawn()
}

public NetworkVariable<int> MyNetworkVariable;
public NetworkList<int> MyListSetOnSpawn;

private void Awake()
{
MyNetworkVariable = new NetworkVariable<int>();
MyNetworkVariable.OnValueChanged += Changed;

MyListSetOnSpawn = new NetworkList<int>();
}

public void Changed(int before, int after)
Expand Down