Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  4. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  5. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    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:
    2,734
  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:
    77
    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. }