Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Sending Dictionaries through Commands and RPCs

Discussion in 'Multiplayer' started by Wattosan, Apr 11, 2016.

  1. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    450
    As of right now, it seems that sending dictionaries is not possible. Also Tuples are not supported by Mono.

    I searched the forums and got a workaround, which consists of converting dict into string and sending that.

    Are there any other good alternatives?

    Cheers,
    Frosty
     
  2. GrymmyD

    GrymmyD

    Joined:
    Dec 2, 2015
    Posts:
    42
    My workaround (which sucks) is to utilize SyncLists with predefined keys for the indices. I too wish there was a "good" prescribed solution from Unity that would allow for easily syncing dicts. Would love to hear better solutions...
     
  3. Kamil-Says

    Kamil-Says

    Joined:
    Jun 30, 2014
    Posts:
    154
    Serialize the dictionary to byte with BinaryFormatter and send it via rpc, the getter has to deserialize the byte stream back to dictionary. That would work.
     
    thegreatzebadiah likes this.
  4. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Here's some code to do what @Kamil Says

    Code (CSharp):
    1. MemoryStream stream = new MemoryStream();
    2. BinaryFormatter formatter = new BinaryFormatter();
    3. try
    4. {
    5.     formatter.Serialize(stream, objectToSerialize);
    6. }
    7. catch (SerializationException e)
    8. {
    9.     Debug.Log("Serialization Failed : " + e.Message);
    10. }
    11. byte[] objectAsBytes = stream.ToArray();
    12. stream.Close();
    Code (CSharp):
    1. SomeObject objectThatWasDeserialized;
    2. MemoryStream stream = new MemoryStream();
    3. stream.Write(objectAsBytes, 0, objectAsBytes.Length);
    4. stream.Seek(0, SeekOrigin.Begin);
    5. BinaryFormatter formatter = new BinaryFormatter();
    6. try
    7. {
    8.     objectThatWasDeserialized = (SomeObject)formatter.Deserialize(stream);
    9. }
    10. catch (SerializationException e)
    11. {
    12.     Debug.Log("Deserialization Failed : " + e.Message);
    13. }
    14. stream.Close();
     
    Kamil-Says likes this.
  5. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    450
    @thegreatzebadiah It's a good idea, however I've now stumbled across another problem. I have a dict:
    Dictionary<Vector3, string>. And unfortunately Vector3 is not serializable. Meaning I have to use a custom serialize class (did some research).

    But I ended up sending string[] instead. Converted Vector3 to string and later converted back to string with a custom function. Feels like a bad hack. At least it works though.
     
  6. GrymmyD

    GrymmyD

    Joined:
    Dec 2, 2015
    Posts:
    42
    This just sends the entirety of the object. I'd much prefer only sending partial updates upon mutation.
     
  7. Kamil-Says

    Kamil-Says

    Joined:
    Jun 30, 2014
    Posts:
    154
    Code (CSharp):
    1. public static class SerializedVector3View
    2. {
    3.     public static byte[] SerializeVector3(DangGamesVector3 vectorObject)
    4.     {
    5.         BinaryFormatter binaryF = new BinaryFormatter();
    6.         using (MemoryStream memoryStream = new MemoryStream())
    7.         {
    8.             binaryF.Serialize(memoryStream,vectorObject);
    9.  
    10.             return memoryStream.ToArray();
    11.         }
    12.     }
    13.  
    14.     public static DangGamesVector3 DeserializeVector3(byte[] dataStream)
    15.     {
    16.         using (MemoryStream memoryStream = new MemoryStream())
    17.         {
    18.             BinaryFormatter binaryF = new BinaryFormatter();
    19.  
    20.             memoryStream.Write(dataStream, 0, dataStream.Length);
    21.             memoryStream.Seek(0, SeekOrigin.Begin);
    22.  
    23.             return (DangGamesVector3)binaryF.Deserialize(memoryStream);
    24.         }
    25.     }
    26. }
    That should work just change it to dictionary
     
    chapdas likes this.
  8. notseanr

    notseanr

    Joined:
    Jan 15, 2016
    Posts:
    22
    You would be better off using NetworkWriter to do the serialization, then SendWriter() or SendBytes.