Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved NetworkDictionary

Discussion in 'Multiplayer' started by Navil, Sep 24, 2023.

  1. Navil

    Navil

    Joined:
    Nov 8, 2014
    Posts:
    4
    Hello,

    for my game I want to save different resources for each player in a dictionary. So the number of wood, oil, stone, ... should be saved in a dictionary.

    However I found out, that Unity does not support networked dictionaries. What is the recommended approach to still replicate those values over the network? I prefer not having a variable for each of them.

    I have a similar problem when (after each turn), I want to show the resources of every player publicly in the game. I would need something like a 3D dictionary (a player has to sync all the resources for each player), and there it would become very nasty.

    Would love to get some input from more experienced unity devs.
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,129
    How many resources do you have really? Is it worth using a divtionary over, for example, six integer fields, one for each resource type?

    Ultimately you will want to transfer ONLY what has changed. So rather than synching the entire number of resources every time a single one of them changes you should prefer synchronizing only the resource that changed, be it oil or wood or …

    Now there are situations where you want to synch all of them at once, for example when connecting or disconnecting. So you‘d put all those resource numbers in the same struct and that implements INetworkSerializable so you can send all resource numbers around in a single RPC call with a single parameter.

    The struct itself could also directly implement each resource type as a field of type NetworkVariable<int> and so you have resource counts automatically synched among players AND you have the option to send all of them via RPC at once.

    The last part you seem to be overthinking. Every client already shares his resource numbers as described above. You store them locally for every client in a non-networked dictionary with player ids as keys.
    You do not have to separately synch these per player resources - every client already has these already available for every other player. In fact you‘d store the local player‘s resource counts in this local dictionary as well.
     
  3. Navil

    Navil

    Joined:
    Nov 8, 2014
    Posts:
    4
    Thank you for your input, that was really helpful.
    I am just having about 8 resources, but at the beginning of the game, 4 of them are selected to be in the game (so 1 game uses 4 out of 8 resources at random). Another game could then have other 4 resources and so on.
    So I could make 8 integer fields for each player and only write to those that are in the game, but it feels kinda counter-intuitive to me, as I would often have to map the enum values to the correct field and the other way around.

    So are you suggesting something in the lines of:?
    Code (CSharp):
    1.  
    2. struct Resources{
    3.   NetworkVariable<int> wood;
    4.   ....
    5. }
    6. NetworkVariable<Resources> resources; //In each player
    7.  
    Ah so a NetworkVariable is not only shared between the Server and the Owner? Would this mean, that every client could technically read all the resources from the other players at all time? As I just want to show them after each turn, wouldn't this be a security and performance issue syncing them all the time across all players?
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,129
    It's been a while but yes I think NetworkVariables are shared among every client and the server.

    If you pick four out of eight resources, you could use a struct with four generic resource-amount fields. Meaning they aren't oil, wood or anything but rather resource 1,2,3 and 4. Somewhere else you'd store what kind of resource 1,2,3,4 are.
     
    Navil likes this.