Search Unity

SyncListStruct: SyncList not initialized

Discussion in 'Multiplayer' started by apocriva, Jun 24, 2015.

  1. apocriva

    apocriva

    Joined:
    Nov 3, 2011
    Posts:
    25
    I have code which looks like this in a NetworkBehaviour:

    Code (csharp):
    1.  
    2.   public struct WorldCell {
    3.      public int x;
    4.      public int y;
    5.      public int terrain;
    6.  
    7.      public WorldCell(FlatHexPoint point, int terrain) {
    8.        this.x = point.X;
    9.        this.y = point.Y;
    10.        this.terrain = terrain;
    11.      }
    12.    }
    13.    public class SyncWorldCells : SyncListStruct<WorldCell> { }
    14.    private SyncWorldCells syncWorldCells = new SyncWorldCells();
    15.  
    When I call anything on syncWorldCells (.Clear(), .Add()), I get the exception "SyncList not initialized". I was referencing the scripting API, and it's not clear what I'm missing. SyncListInt works fine.

    http://docs.unity3d.com/ScriptReference/Networking.SyncListStruct_1.html
     
  2. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    This appears to be a bug. If the derived class name doesn't contain the string "SyncList", it is not processed properly.

    If you use "class SyncListWorldCells" it will work. I'll file a bug.
     
  3. apocriva

    apocriva

    Joined:
    Nov 3, 2011
    Posts:
    25
    That did the trick! Thanks! :)

    I sometimes forget that there's a bunch of reflection voodoo going on under the hood. ;)
     
  4. apocriva

    apocriva

    Joined:
    Nov 3, 2011
    Posts:
    25
    Additional possible issue: when the specified callback is called in response to an OP_ADD operation, the index that I'm receiving is always 0, rather than the index of the new element. (Unsure if this applies to other operations.)
     
  5. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    Add() always adds at the end of the list.. so the index would always be size-1.

    This is probably because the synclist add message does not include the index - since it is always added at the end.. but it is a bit strange for the user.
     
  6. apocriva

    apocriva

    Joined:
    Nov 3, 2011
    Posts:
    25
    Yeah, it is certainly simple enough to deal with, it's just that the callback has an index parameter, and it surprised me that it wasn't the right index. :)

    One last thing -- when a client connects, the SyncList I have isn't getting synced automatically, so the new client's local version of the SyncList is empty. Is this intended behaviour?
     
  7. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    SyncList contents are sent to client with other SyncVars on the object. they should be initialized.
     
  8. apocriva

    apocriva

    Joined:
    Nov 3, 2011
    Posts:
    25
    Yes yes, of course it is! I just wasn't receiving anything via the callback and didn't handle the initial sync, which has already taken place by the time OnStartClient() has been called. :)

    Thanks!
     
  9. Quenestil

    Quenestil

    Joined:
    Jul 2, 2014
    Posts:
    3
    Thank you both!

    I didn't know that the list's name should start with SyncList, since it's not in the documentation.

    Saved my day!
     
  10. Aravol

    Aravol

    Joined:
    Mar 9, 2015
    Posts:
    1
    Had the same issue. Extra addendum - this SyncList___ only works if it's a subclass of the script attempting to use it for synchronization. The underlying struct does not need to be, however.

    Not sure if this counts as a bug, so I've opened a feature request to remove at least this part of said requirement.
     
  11. nonlin

    nonlin

    Joined:
    Dec 12, 2013
    Posts:
    46
    How did you get SyncList to sync I can't get them to sync? I don't understand what you did good sir.
     
  12. Tinjaw

    Tinjaw

    Joined:
    Jan 9, 2014
    Posts:
    518
    I have prefixed my SyncListStruct class with SyncList, however it is not getting synced. I see things fine on the host, but the client side is null. Anybody got a working example of a SyncListStruct?
     
    pKallv and banyango like this.
  13. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    Will this type of behavior be changed in the future, so that it will not be strange to the users?
     
  14. banyango

    banyango

    Joined:
    Mar 31, 2014
    Posts:
    19
    Did you ever solve this? I am experiencing the same issue. Where the synclist is null on the client.
     
  15. Tinjaw

    Tinjaw

    Joined:
    Jan 9, 2014
    Posts:
    518
    Yes, I did. But I don't remember off hand what fixed things. I am just leaving work now. If you don't get things working in 16 hours from this post, ping me and I will try to put together a working example for you.
     
  16. DanielDollerup

    DanielDollerup

    Joined:
    Sep 18, 2013
    Posts:
    8
    Hey guys,

    I'm getting the same problem as the author, I've tried several things to fix this issue, but I can't seem to get it to work.
    This is my code atm, and I'm getting the error:

    SyncList not initialized

    The error comes when i try to Add() to the list.

    Code (CSharp):
    1.     public struct PlayerInfo
    2.     {
    3.         public Team team;
    4.         public string username;
    5.         public int connectionId;
    6.         public int avatarID;
    7.         public float joined;
    8.         public override string ToString()
    9.         {
    10.             return username + "_" + connectionId;
    11.         }
    12.     }
    13.     public class SyncListPlayerInfo : SyncListStruct<PlayerInfo> { }
    14.  
    15.     [SerializeField]
    16.     private SyncListPlayerInfo syncListPlayerInfo = new SyncListPlayerInfo();

    Any help will be greatly appriciated.
     
  17. DanielDollerup

    DanielDollerup

    Joined:
    Sep 18, 2013
    Posts:
    8
    Scrap that, I didn't fix it. I still get the problem on the Client

    SyncList not initialized

    Still need help! :)
     
  18. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    I'm pretty sure it has to do with initializing it in the OnStartClient() or something other than Awake(). Try and test to see if there are other ways you can call the initialization process.
     
    kaimikael likes this.
  19. Salvation-Au

    Salvation-Au

    Joined:
    Jan 17, 2016
    Posts:
    13
    I believe the issue here is to do with authority. The object in question is, on the client, a non authoritative object. The unity documentation does indicate that the a synclist is "synchronized from the server to clients". The below may only be a work around but it has worked for my application.

    I have solved this for my self by doing the following using DanielDollerup's example in the below code.


    Code (CSharp):
    1.  
    2.     NetworkClient _client;
    3.     const short PlayerInfoMessage = 1002;
    4.  
    5.     void Start()
    6.     {
    7.         _client = NetworkManager.singleton.client;
    8.         NetworkServer.RegisterHandler(PlayerInfoMessage, UpdateVoxelToServer);
    9.     }
    10.  
    11.     //........ some method
    12.     PlayerInfo p = syncListPlayerInfo[value];
    13.     p.team = Team.Red;
    14.     TransmitValues(p);
    15.     //.......
    16.  
    17.     [ClientCallback]
    18.     void TransmitValues(PlayerInfo player)
    19.     {
    20.         PlayerInfoMessage p = new PlayerInfoMessage();
    21.         p.player = player;
    22.         _client.Send(PlayerInfoMessage, p);
    23.     }
    24.  
    25.     class PlayerInfoMessage : MessageBase
    26.     {
    27.         PlayerInfo player;
    28.         public PlayerInfoMessage() { }
    29.  
    30.         public override void Deserialize(NetworkReader reader)
    31.         {
    32.             player.team = reader.ReadByte(); //You will have to look at breaking this down to the Team struct but is is here for reference
    33.             player.username = reader.ReadString();
    34.             player.connectionId = reader.ReadInt32();
    35.             player.avatarID = reader.ReadInt32();
    36.             player.joined = reader.ReadSingle();
    37.  
    38.         }
    39.  
    40.         public override void Serialize(NetworkWriter writer)
    41.         {
    42.             writer.Write(player.team);//You will have to look at breaking this down to the Team struct but is is here for reference
    43.             writer.Write(player.username);
    44.             writer.Write(player.connectionId);
    45.             writer.Write(player.joined);
    46.         }
    47.     }
    48. ;
     
  20. MakinStuffLookGood

    MakinStuffLookGood

    Joined:
    Nov 20, 2012
    Posts:
    21
    Ran into this issue, also was getting the List object as null when a client joined up (when trying to register the CallBack).

    The solution for me was to define the class being used as the List inside the scope of the NetBehaviour using that list. This isn't ideal but it works.

    Code (CSharp):
    1.     private class SyncListNetSprite : SyncListStruct<NetSprite> { }
    2.     SyncListNetSprite _netSprites = new SyncListNetSprite();
    3.  
    4.     public override void OnStartClient() {
    5.         _netSprites.Callback = NetSpriteListCallback;
    6.     }
    7.  
    This worked. But I originally I had SyncListNetSprite defined else where (specifically, in the file with the associated struct NetSprite). That was causing the line where I subscribe to the callback event to throw a null reference exception.
     
  21. LetsBeHanus

    LetsBeHanus

    Joined:
    May 28, 2016
    Posts:
    2
    I keep having this error when I initialize my SyncListStruct. I only get this error on the Client side. Anyone know what this error means? If I make the GameObject with my SyncList class and struct on it have Server Only authority, the error does not appear as well. Snip20160719_3.png
     
    Last edited: Jul 19, 2016
  22. Insurecti

    Insurecti

    Joined:
    Apr 13, 2018
    Posts:
    5
    Hello ppl. Anyone running into this issue yet? I just fell into the same.

    My condition: Had inside a function:
    Code (CSharp):
    1.  
    2. public class SomeClass : NetworkBehaviour    
    3.     ...
    4.     public bool SomeFunction(<T> args)
    5.     {
    6.         ...
    7.         SyncListStructType SomeVar = new SyncListStructType();
    8.         ...
    9.         SomeVar.Add(someinfo);
    10.         ...
    11.     }
    12. }
    Then compiler would throw "SyncList not initialized" at runtime.

    How I fixed it:
    • Moved declaration to class variables
    Code (CSharp):
    1.  
    2. public class SomeClass : NetworkBehaviour
    3. ...
    4. SyncListStructType SomeVar = new SyncListStructType();
    5. ...
    6.     public bool SomeFunction(<T> args)
    7.     {
    8.         ...
    9.         SomeVar.Add(someinfo);
    10.         ...
    11.     }
    12. }
    My hypothesis: SyncListStructure variables won't be initialized unless at class structure.

    Looking forward for validation from you ppl! :)
     
    mdrunk likes this.
  23. mdrunk

    mdrunk

    Joined:
    Apr 26, 2014
    Posts:
    11

    ^ this right here