Unity-Technologies / com.unity.netcode.gameobjects

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.
MIT License
2.15k stars 435 forks source link

WriteDelta does not work correctly for NetworkVariable<List<Class>> due to incorrect handling of duplicates in ListSerializer #3087

Closed harayuu9 closed 3 weeks ago

harayuu9 commented 1 month ago

Title

WriteDelta does not work correctly for NetworkVariable<List<Class>> due to incorrect handling of duplicates in ListSerializer

Description

The Duplicate method in the ListSerializer does not make copies of the instances within the list. As a result, when the number of elements in the list changes, it marks the list as Dirty correctly, but changes to the contents of the class instances within the list do not trigger the Dirty state.
The Class in question implements INetworkSerializable and IEquatable as expected, so this behavior is unexpected. Since a simple solution isn’t apparent, I recommend adding a managed version of NetworkList. Additionally, implementing an ILPP error for cases like this would be beneficial.

Reproduce Steps

  1. Create a class containing a NetworkVariable<List<Class>>.
  2. Add elements to the list and confirm that it correctly triggers the Dirty state.
  3. Modify a property of an instance within the list.
  4. Observe that it does not trigger the Dirty state.

Actual Outcome

Modifying the properties of instances within the list does not trigger WriteDelta, and the list does not enter the Dirty state.

Expected Outcome

Modifying the properties of instances within the list should trigger the Dirty state for the list as a whole.

Screenshots

(If applicable, add screenshots to help explain your problem)

Environment

Additional Context

Additional context related to the problem is provided below.
Please include logs or code snippets, and if possible, attach a minimal Unity project that reproduces the issue.

harayuu9 commented 1 month ago

It doesn’t seem to be an issue with the Dirty flag not being set; rather, it appears to be a problem with WriteDelta in ListSerializer not writing correctly. As an experiment, I replaced WriteDelta with Write(writer, ref value); and similarly modified the Read method, which resolved the issue. Since you have to manually set the Dirty flag for Lists, I still recommend using the Managed version of NetworkList.

NoelStephensUnity commented 1 month ago

@harayuu9

3081 should get back ported soon to NGO v1.x.x and will be in the NGO v1.12.0 update.

I believe the updates in that PR will resolve the issue you are experiencing with using NetworkVariable<List<Class>>.

harayuu9 commented 1 month ago

@NoelStephensUnity Thank you, I'll check it out when it's backported.

harayuu9 commented 3 weeks ago

I tried the new version(2.xx) and it was fixed. Thank you.