Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question "Don't know how to serialize List`1 " When using NetworkList

Discussion in 'Netcode for GameObjects' started by Manic_MG, Jan 21, 2022.

  1. Manic_MG

    Manic_MG

    Joined:
    Apr 30, 2015
    Posts:
    13
    Hello, sorry if this is a simple one, but I'm completely new to NetCode for GameObjects and lost.
    I am attempting to use a NetworkList as I need to transmit a series of 52 or more floats. However I am receiving compile errors that occur in the Rpc function.
    "Assets\Scripts\AVNetworkController.cs(116,14): error - Don't know how to deserialize List`1 - implement INetworkSerializable or add an extension method for FastBufferReader.ReadValueSafe to define serialization."
    upload_2022-1-22_1-48-56.png
    Here is a snippet of the code:

    Code (CSharp):
    1.  
    2. [SerializeField]
    3. public NetworkList<float> NetworkFKList;
    4.  
    5. private void Start()
    6.    {
    7.       NetworkFKList = new NetworkList<float>();
    8.       for (int i = 0; i < 52; i++)
    9.          {
    10.             NetworkFKList.Add(0f);
    11.          }
    12. //Somewhere in here newFKList is populated with values I need that I am attempting to transfer to NetworkFKList
    13. [ServerRpc]
    14. public void UpdateFaceKeysServerRpc(List<float> newFKList)
    15.     {
    16.         for (int i = 0; i < newFKList.Count; i++)
    17.         {
    18.             NetworkFKList[i] = newFKList[i];
    19.            // I have also tried NetworkFKList.Add(newFKList[i]);
    20.         }
    21.     }
    Am I using NetworkLists wrong?, is this not their purpose?
     
    Last edited: Jan 21, 2022
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    674
    The error isn't related to NetworkList but trying to pass a list to the server RPC. You can pass arrays so use an array of floats at this point instead of a list.
     
    luke-unity likes this.
  3. Manic_MG

    Manic_MG

    Joined:
    Apr 30, 2015
    Posts:
    13
    Sweet that worked!. Thanks
    Code (CSharp):
    1.     [ServerRpc]
    2.     public void UpdateFaceKeysServerRpc(float[] sentFKArray)
    3.     {
    4.  
    5.         for (int i = 0; i < 52; i++)
    6.         {
    7.             NetworkFKList[i] = sentFKArray[i];
    8.         }
    9.     }
    The only issue I'm running into now is a buffer size limit, looks like I'm exceeding it.
    But it looks like there are a few threads from people experiencing similar issues so I'll look there.
     

    Attached Files:

  4. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    674
    Update Netcode to pre.4 if you haven't already, it fixes a bug where you quickly reached a limit of how much you could add to a NetworkList.
     
  5. Manic_MG

    Manic_MG

    Joined:
    Apr 30, 2015
    Posts:
    13
    I am currently using pre.4

    Should this not normally be happening using the NetworkList?
    I just assumed I was sending too much data and there was a way to increase the limit somehow. I haven't had a chance to attempt that yet.
     
  6. Manic_MG

    Manic_MG

    Joined:
    Apr 30, 2015
    Posts:
    13
    Here's an example of the kind of floats I'm sending. It's OSC data from IOS ARKit face tracking. I'm converting it to a list in order to send it over a multiplayer game. These 52 values update 30 times a second (running project at 30fps)
    Code (CSharp):
    1. 0.1011367216706276
    2. 0.29201051592826843
    3. 0.2936050593852997
    4. 0.0
    5. 0.0
    6. 0.11452288180589676
    7. 0.11481111496686935
    8. -0.6710376143455505
    9. -0.6677505373954773
    10. 0.139095738530159
    11. -0.14511656761169434
    12. -0.008100325241684914
    13. 0.026931222528219223
    14. -0.061308275908231735
    15. -0.06132631376385689
    16. 0.15053518116474152
    17. 0.1505589783191681
    18. 0.3570777475833893
    19. 0.3565797209739685
    20. 0.010035885497927666
    21. 0.025939203798770905
    22. 0.035172563046216965
    23. -0.02708432264626026
    24. -0.03149525076150894
    25. -0.003989010583609343
    26. -0.027976475656032562
    27. 0.025100162252783775
    28. -0.0005838338402099907
    29. 0.04119766131043434
    30. 0.07112914323806763
    31. -0.011954116635024548
    32. 0.0
    33. -0.02208051085472107
    34. -0.04752753674983978
    35. 0.005517500452697277
    36. -0.008611667901277542
    37. 0.008307084441184998
    38. -0.17919869720935822
    39. -0.15959085524082184
    40. 0.041160061955451965
    41. 0.023376038298010826
    42. -0.02457955665886402
    43. -0.023629918694496155
    44. -0.013307630084455013
    45. -0.010534528642892838
    46. -0.035656966269016266
    47. -0.03259516879916191
    48. -0.010734405368566513
    49. -0.009134470485150814
    50. 0.008960368111729622
    51. -0.0008349923882633448
    52. -1.0189183541342572e-07
     
  7. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    674
    I wouldn't have expected to hit a limit with that amount of data. Are you clearing the list each time or is it accumulative? I'll have to try it out myself.
     
  8. Manic_MG

    Manic_MG

    Joined:
    Apr 30, 2015
    Posts:
    13
    Hmm, I did make a mistake. I was adding the 52 floats twice
    But I've fixed this and the errors still exists. I added a quick Debug.Log to check the lengths / counts as well as the values themselves to ensure they're remaining at 52 and the values are there.
    Code (CSharp):
    1.     public void UpdateFaceKeysServerRpc(float[] sentFKArray)
    2.     {
    3.  
    4.         for (int i = 0; i < sentFKArray.Length; i++)
    5.         {
    6.             NetworkFKList[i] = sentFKArray[i];
    7.         }
    8.  
    9.  
    10.         Debug.Log("NEW ARRAY, Length = " + sentFKArray.Length);
    11.         for (int i = 0; i < sentFKArray.Length; i++)
    12.         {
    13.             Debug.Log(sentFKArray[i]);
    14.         }
    15.  
    16.  
    17.         Debug.Log("NEW NETWORKLIST, Length = " + NetworkFKList.Count);
    18.         for (int i = 0; i < NetworkFKList.Count; i++)
    19.         {
    20.             Debug.Log(NetworkFKList[i]);
    21.         }
    22.     }
    Code (CSharp):
    1. NEW NETWORKLIST, Length = 52
    2. -0.09315924
    3. 0.2538644
    4. 0.2538856
    5. 0
    6. 0
    7. 0
    8. 0
    9. -0.6203992
    10. -0.6172931
    11. 0.1109501
    12. -0.1417809
    13. -0.008100325
    14. 0
    15. -0.06130828
    16. -0.06132631
    17. 0.09946179
    18. 0.0994793
    19. 0.2214654
    20. 0.2214648
    21. 0.06251084
    22. 0.02068622
    23. 0.01802551
    24. -0.008629035
    25. 0.0007583712
    26. -0.015517
    27. -0.02099421
    28. 0
    29. 0.007778692
    30. 0.1041044
    31. 0.3380764
    32. -0.0006523338
    33. 0
    34. -0.02800294
    35. -0.05935419
    36. 0.05316978
    37. 0.05798394
    38. 0.003470858
    39. -0.1791987
    40. -0.1595909
    41. 0.1008237
    42. 0.1104052
    43. -0.0311375
    44. -0.03060791
    45. -0.008074892
    46. -0.005112974
    47. -0.04285654
    48. -0.04221743
    49. 0.02626065
    50. 0.02309331
    51. 0.01022728
    52. 0.001209655
    53. -1.281316E-07
    54. NEW ARRAY, Length = 52
    55. -0.09315924
    56. 0.2538644
    57. 0.2538856
    58. 0
    59. 0
    60. 0
    61. 0
    62. -0.6203992
    63. -0.6172931
    64. 0.1109501
    65. -0.1417809
    66. -0.008100325
    67. 0
    68. -0.06130828
    69. -0.06132631
    70. 0.09946179
    71. 0.0994793
    72. 0.2214654
    73. 0.2214648
    74. 0.06251084
    75. 0.02068622
    76. 0.01802551
    77. -0.008629035
    78. 0.0007583712
    79. -0.015517
    80. -0.02099421
    81. 0
    82. 0.007778692
    83. 0.1041044
    84. 0.3380764
    85. -0.0006523338
    86. 0
    87. -0.02800294
    88. -0.05935419
    89. 0.05316978
    90. 0.05798394
    91. 0.003470858
    92. -0.1791987
    93. -0.1595909
    94. 0.1008237
    95. 0.1104052
    96. -0.0311375
    97. -0.03060791
    98. -0.008074892
    99. -0.005112974
    100. -0.04285654
    101. -0.04221743
    102. 0.02626065
    103. 0.02309331
    104. 0.01022728
    105. 0.001209655
    106. -1.281316E-07
    Maybe I can throw together something generic for testing.
     
  9. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    674
    I was able to add 200 floats but with 300 I got the same error. I tried UNet and Unity transports with various settings but with no difference so I guess the buffer is handled higher up. Have you got any other network traffic going on at the same time, in case that's eating into the same buffer.
     
  10. Manic_MG

    Manic_MG

    Joined:
    Apr 30, 2015
    Posts:
    13
    The initial OSC values are sent over my network (either over WiFi or Lan).
    But I've turned that off and just replaced my current setup with a generic component that I can run without all that stuff and I still get the error.
    I'm not sure what the best way to send component is but here it is. It just gets attached to the Player prefab (+ a Network Controller) that gets spawned from the built in Network Manager
    Code (CSharp):
    1. using Unity.Netcode;
    2. using UnityEngine;
    3.  
    4. public class NetworkListTester : NetworkBehaviour
    5. {
    6.     [SerializeField]
    7.     public NetworkList<float> NetworkFKList;
    8.     public float[] FKArray = new float[52];
    9.     // Start is called before the first frame update
    10.  
    11.     private void Awake()
    12.     {
    13.     }
    14.     private void Start()
    15.     {
    16.         if (IsServer)
    17.         {
    18.         }
    19.         if (IsClient && IsOwner)
    20.         {
    21.             //Populating array and NetworkList with 52 0f values
    22.             for (int i = 0; i < 52; i++)
    23.             {
    24.                 FKArray[i] = (0);
    25.                 NetworkFKList.Add(0f);
    26.             }
    27.         }
    28.     }
    29.     private void UpdateServer()
    30.     {
    31.     }
    32.     private void UpdateClient()
    33.     {
    34.         for (int i = 0; i < FKArray.Length; i++)
    35.         {   //Normally this sets values in FKArray to the /W OSC values in the facekey dictionary
    36.             //Just using a float that you would typically see from OSC ARKit face tracking
    37.             FKArray[i] = -0.0006523338f;
    38.         }
    39.         UpdateFaceKeysServerRpc(FKArray);
    40.     }
    41.  
    42.     // Update is called once per frame
    43.     private void Update()
    44.     {
    45.         if (IsServer)
    46.         {
    47.             UpdateServer();
    48.         }
    49.         if (IsClient && IsOwner)
    50.         {
    51.             UpdateClient();
    52.         }
    53.     }
    54.  
    55.     [ServerRpc]
    56.     public void UpdateFaceKeysServerRpc(float[] sentFKArray)
    57.     {
    58.  
    59.         for (int i = 0; i < sentFKArray.Length; i++)
    60.         {
    61.             NetworkFKList[i] = sentFKArray[i];
    62.         }
    63.  
    64.         //---Debug.Logs to ensure Array and Network list have 52 floats---
    65.  
    66.         Debug.Log("NEW ARRAY, Lenth = " + sentFKArray.Length);
    67.         //---Log each value---
    68.         //for (int i = 0; i < sentFKArray.Length; i++)
    69.         //{
    70.         //    Debug.Log(sentFKArray[i]);
    71.         //}
    72.         //
    73.         Debug.Log("NEW NETWORKLIST, Lenth = " + NetworkFKList.Count);
    74.         //---Log each value---
    75.         //for (int i = 0; i < NetworkFKList.Count; i++)
    76.         //{
    77.         //    Debug.Log(NetworkFKList[i]);
    78.         //}
    79.     }
    80. }
    81.  
    There's a good chance I'm just doing something totally wrong though. Thanks for the help so far.
     
  11. Manic_MG

    Manic_MG

    Joined:
    Apr 30, 2015
    Posts:
    13
    And just to be sure, here's the error code:
    Code (CSharp):
    1. OverflowException: Writing past the end of the buffer
    2. Unity.Netcode.NetworkList`1[T].WriteDelta (Unity.Netcode.FastBufferWriter writer) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/NetworkVariable/Collections/NetworkList.cs:125)
    3. Unity.Netcode.NetworkVariableDeltaMessage.Serialize (Unity.Netcode.FastBufferWriter writer) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/Messaging/Messages/NetworkVariableDeltaMessage.cs:77)
    4. Unity.Netcode.NetworkBehaviour.NetworkVariableUpdate (System.UInt64 clientId, System.Int32 behaviourIndex) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/Core/NetworkBehaviour.cs:548)
    5. Unity.Netcode.NetworkBehaviour.VariableUpdate (System.UInt64 clientId) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/Core/NetworkBehaviour.cs:494)
    6. Unity.Netcode.NetworkBehaviourUpdater.NetworkBehaviourUpdate (Unity.Netcode.NetworkManager networkManager) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/Core/NetworkBehaviourUpdater.cs:36)
    7. Unity.Netcode.NetworkManager.OnNetworkManagerTick () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/Core/NetworkManager.cs:1241)
    8. Unity.Netcode.NetworkTickSystem.UpdateTick (System.Double localTimeSec, System.Double serverTimeSec) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/Timing/NetworkTickSystem.cs:96)
    9. Unity.Netcode.NetworkManager.OnNetworkPreUpdate () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/Core/NetworkManager.cs:1208)
    10. Unity.Netcode.NetworkManager.NetworkUpdate (Unity.Netcode.NetworkUpdateStage updateStage) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/Core/NetworkManager.cs:1155)
    11. Unity.Netcode.NetworkUpdateLoop.RunNetworkUpdateStage (Unity.Netcode.NetworkUpdateStage updateStage) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/Core/NetworkUpdateLoop.cs:149)
    12. Unity.Netcode.NetworkUpdateLoop+NetworkPreUpdate+<>c.<CreateLoopSystem>b__0_0 () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.4/Runtime/Core/NetworkUpdateLoop.cs:196)
    13.  
     
  12. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    674
    You could try slowing down the rate at which you're sending the updates to the server to see if it makes a difference, in case the server is accumulating those updates then making multiple update changes to the list at once. I don't know how this governed though, I assume by the server tick rate.
     
  13. Manic_MG

    Manic_MG

    Joined:
    Apr 30, 2015
    Posts:
    13
    Ok did some testing. I didn't exactly fix it but...Increasing my Tick Rate to 120 seems to fix it

    That may have been what you meant with "You could try slowing down the rate".
    I just didn't even try going higher because I assumed that would make the issue worse.
    I guess it all accumulates if it cant all be sent in 1 frame/tick and if you don't get it out fast enough you overflow the buffer? I don't understand half of this but that's my guess.
    I'm using the U Net Transport and it didn't matter how large I made my buffer or queue size or tried Immediately or Queued mode it would overflow.
    I don't know what the implications are of having my tick rate so high (maybe network saturation)? But I'm just gonna go with it until things are a little more clear.

    Going to 60 even works. I set it to 30 originally because I assumed matching tick rate and frame rate was ideal? (My project is locked at 30)
     
    Last edited: Feb 5, 2022
  14. Manic_MG

    Manic_MG

    Joined:
    Apr 30, 2015
    Posts:
    13
    Ok I messed up, super stupid oversight - turns out my frame limit was disabled and I was running uncapped around 120fps with tick rate at 30.

    So I guess if the tick rate is lower than the frame rate it can cause overflow with enough floats in a list?
    Setting FPS to 30 with Tick Rate of 30 is fine now. But I might set it higher for safety.
     
    trombonaut likes this.
  15. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    674
    I'm assuming that's the case, glad you got it sorted anyway. There's meant to be a fix coming allowing for custom buffer sizes which I hope will mean an end to this issue. You'll just need to switch over to the Unity Transport.