Search Unity

  1. Unity 2019.1 beta is now available.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We're looking for insight from anyone who has experience with game testing to help us better Unity. Take our survey here. If chosen to participate you'll be entered into a sweepstake to win an Amazon gift card.
    Dismiss Notice
  4. On February 28th the Feedback website will shut down and be redirected to the Unity forums. See the full post for more information.
    Dismiss Notice
  5. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  6. Unity 2018.3 is now released.
    Dismiss Notice
  7. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Client sees only default value of SyncListStruct members

Discussion in 'Connected Games' started by acc_cmwolke, Jul 11, 2018.

  1. acc_cmwolke

    acc_cmwolke

    Joined:
    Aug 29, 2017
    Posts:
    2
    Hi guys!

    I am scratching my head over this one, so maybe you can help out. I have a shared "checklist", which can be modified by the users (both clients and servers). Now, adding the items to the SyncListStruct containing the ChecklistItems works wonderfully - the only issue I have is that the clients are unable to read the individual item's values - they're all default (null / false).

    This is the shared checklist, whose functions are called via command from the client.

    Code (CSharp):
    1. public class SharedChecklistState : NetworkBehaviour {
    2.  
    3. [SyncVar]
    4. public CheckListList Checklist;
    5. [SyncVar]
    6. public float UpdateToken;
    7.  
    8. private static SharedChecklistState instance;
    9. public static SharedChecklistState Instance
    10. {
    11. get
    12. {
    13. return instance;
    14. }
    15. }
    16.  
    17.  
    18. protected virtual void Awake()
    19. {
    20. if (instance != null)
    21. {
    22. Debug.LogErrorFormat("Trying to instantiate a second instance of singleton class {0}", GetType().Name);
    23. }
    24. SharedChecklistState.instance = (SharedChecklistState)this;
    25. }
    26.  
    27. public void AddItem(string text, string GUID)
    28. {
    29. this.Checklist.Add(new ChecklistItem(GUID, text, false));
    30. this.UpdateTimeStamp();
    31. }
    32.  
    33. public void SetItem(bool value, string ID)
    34. {
    35. ChecklistItem item = this.GetItemByID(ID);
    36. if (item.ID != null)
    37. {
    38. int index = this.Checklist.IndexOf(item);
    39. item.done = value;
    40. this.Checklist[index] = item;
    41. }
    42.  
    43. this.UpdateTimeStamp();
    44. }
    45.  
    46. public void RemoveItem(string ID)
    47. {
    48. ChecklistItem item = this.GetItemByID(ID);
    49. if (item.ID != null)
    50. {
    51. this.Checklist.Remove(item);
    52. }
    53. this.UpdateTimeStamp();
    54. }
    55.  
    56. public void UpdateTimeStamp()
    57. {
    58. this.UpdateToken = Time.time;
    59. }
    60.  
    61. private ChecklistItem GetItemByID(string ID)
    62. {
    63. return this.Checklist.First(x => x.ID == ID);
    64. }
    65. }
    66.  
    67. [System.Serializable]
    68. public struct ChecklistItem
    69. {
    70.     public string ID { get; set; }
    71.     public string text { get; set; }
    72.     public bool done { get; set; }
    73.  
    74.     public ChecklistItem(string ID, string text, bool done)
    75.     {
    76.         this.ID = ID;
    77.         this.text = text;
    78.         this.done = done;
    79.     }
    80. }
    81.  
    82. public class CheckListList : SyncListStruct<ChecklistItem> { }
    Client-sided the change is picked up perfectly fine with the changed update token. They then access the checklist via

    foreach (ChecklistItem item in SharedChecklistState.Instance.Checklist) { ... }


    which *does* execute exactly the amount of times there are items in the checklist. But all items (for example when printed out with item.ID / item.text / item.done) are their default values on the client. The server gets the actual values. When adding items client-side, the server still gets the correct value.

    What am I missing?
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    4,472
  3. acc_cmwolke

    acc_cmwolke

    Joined:
    Aug 29, 2017
    Posts:
    2
    I did try both and either - having it not as Syncvar and initializing it, still same problem
     
  4. Ellernate

    Ellernate

    Joined:
    Aug 25, 2017
    Posts:
    81
    Just tested this and you're correct this is a bug. SyncListStruct apparently doesn't work with properties, and the unet weaver fails to catch this.

    Simply change your struct to use fields instead and it should work.


    Code (CSharp):
    1. public struct ChecklistItem
    2. {
    3.     public string ID;
    4.     public string text;
    5.     public bool done;
    6.     public ChecklistItem(string ID, string text, bool done)
    7.     {
    8.         this.ID = ID;
    9.         this.text = text;
    10.         this.done = done;
    11.     }
    12. }