Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    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. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    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:
    3,832
  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. }