Has anyone been able to get SyncList Structs to work?

My project uses structs to define a bunch of parameters on generic prefabs which represent various game pieces in the world.

I’ve managed to get all my other networking code working just fine, but SyncList Struct is damaging my calm.

I’ve been all over the Unity docs and forums for days, and I have yet to find a single working example of a complete SyncList Struct that works (changes to the struct work, and actually propagate to the remote clients).

I even grabbed the Unet SyncList source code and, while quite enlightening, still does not give me what I need to know to successfully access (read, write, call constructors, etc) with the Unet implementation of the Struct class.

I’m used to using “normal” structs, but the Unet SyncList implementation of the struct is obscuring all the usual means to access the struct. I’m not even worried about the network propagation yet, just getting access to the struct is confounding me.

I’m in a tough spot because I’m at the low end of intermediate at C#, so I’m not comfortable (yet) just jumping in and writing my own custom Serializer/Deserializer or whatnot (which others have resorted to when they failed to get SyncList Struct to work).

Any tips would be greatly appreciated.

In order for the changes to get to the clients, SyncListStructs have to be modified on the server (that’s the only thing I had problems with at first as I was modifying them on the client). Other than that, the only other special thing is that you need to set them up a SyncListStruct specially. After that, it’s easy enough to do whatever you want to them (at least in my case it was, and I’m not that great at C# either).

2 Likes
public class PlayerStatsSyncClass : SyncListStruct<PlayerStats>{}

public PlayerStatsSyncClass playerStatsList = new PlayerStatsSyncClass();

public Struct PlayerStats()
{
   public int lvl;
   public int maxLvl;
   public float hp;
   public float maxHp;
}

This is base setup, you could find it in Script Reference, you can also add Callback if you wish.

And then if you want the client to change it you use [Command]

[Command]
public void CmdAddStructToList(int lvl, int maxLvl, float hp, float maxHp)
{
   playerStatsList.Add(new PlayerStats(lvl, maxLvl, hp, maxHp));
}

from the server you can simply use:

[Server]
public void AddStructToList...
2 Likes

The trick with SyncListStruct is you cannot just set a field inside the struct… it will not synchronize to client if you do this.

You must completely reset the entire struct in order to SetDirtyBit and get the struct to synchronize to client.

MySyncStruct.field1 = 5.7f; //NO NO NO!!!!  Don't do this.  It won't sync if you change internal fields of the struct.  Unless you manually SetDirtyBit.

SomeStruct structTemp = new Struct(5.7f);
MySyncStruct = structTemp; //This works, you need to set the entire SyncStruct.

Well I had the same problem before I looked how structs work. They are not made to be changed, if you want something to be changed you use class. Anyway, for example you got:

transform.position.x = 10; // it won't work, it's a struct

you would use

transform.position.Set(new Vector(10, 0, 0));

Look for some tutorials/information how structs work, thats what I did to understand it better :slight_smile:

1 Like

@Chom1czek ,

Thanks, man (or woman)!

This was just the hint I needed to get me over the hump. This is all working nicely now.

I was very close. I had two issues.

  1. I did not have my struct set up just how the SyncList needed it.
  2. I was not calling playerStatsList.Add correctly.

Your post exposed both of those issues.

Thanks again! You really got me out of a endless debug spiral.

Glad that I could help. I been there and done that… but I think I am finally managed to understood and use it well enough :slight_smile:

Where should the code be located, at the player?