Search Unity

Feature Request JsonUtility can't serialize Dictionary

Discussion in 'Editor & General Support' started by vladk, Mar 22, 2021.

  1. vladk

    vladk

    Joined:
    Jul 10, 2008
    Posts:
    167
    Why, Unity? Like... it's a dictionary!! It's literally a json! I'd understand if I was asking something vastly complicated and you were like "nah, dude, too hard". But it's a dictionary! Why can't you just loop over keys and shove them into a string???
     
    Daniel-F likes this.
  2. fffMalzbier

    fffMalzbier

    Joined:
    Jun 14, 2011
    Posts:
    3,276
    If you want to use dictionarys take a look at json.net.
    Unity did optimize the JsonUtility for speed and does not support all possible features.
     
  3. MassimoFrancesco

    MassimoFrancesco

    Joined:
    Jul 6, 2019
    Posts:
    44
    Since version 2020.3 Unity already includes the "Json .NET" (v12) as a package found in the package manager.

    Note that the "Json .Net for Unity" asset on the store is outdated and runs on v8 or something. Still works, according to reviews, but it is quite interesting that Unity now includes the latest Github project as a semi-official package.

    After import just use

    string json = JsonConvert.SerializeObject(object);


    instead of the "old"
    string json = JsonUtility.ToJson(object);


    It serializes Dictionaries properly.

    Here you find the official docs:
    https://www.newtonsoft.com/json/help/html/Introduction.htm
     
  4. MimiKitty

    MimiKitty

    Joined:
    Dec 13, 2018
    Posts:
    20
    I can't find this in the package manager or any info on the package when googling
     
    Daniel-F likes this.
  5. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,911
  6. MimiKitty

    MimiKitty

    Joined:
    Dec 13, 2018
    Posts:
    20
  7. Daniel-F

    Daniel-F

    Joined:
    May 15, 2013
    Posts:
    26
    Good info but this still doesn't explain why Unity doesn't just add this basic functionality to the built-in utility? Is there no native equivalent of a Dictionary on some platforms?
     
    Last edited: Apr 8, 2023
  8. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,911
    The simple answer is that JsonUtility uses the same serialization mechanism as the rest of Unity (the same one used for serializing asset files, scene files, Instantiate, etc) and that serialization mechanism does not support dictionaries.

    The longer answer is that serializing Dictionaries would add a lot of complexity to an otherwise very simple and performant framework which is optimized for speed. Unity's serializer is fast, and since the workarounds for a serialized Dictionary are pretty simple, it's not worth sacrificing performance for it.
     
    Wappenull and Ryiah like this.
  9. masta-yoda

    masta-yoda

    Joined:
    Apr 19, 2020
    Posts:
    91
    what is the workaround? I'm developing a library (asset) and don't want to pull an extra Newtonsoft.Json dependency for this small task, because that will force all my users to pull the same dependency as well.
     
  10. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    That's not a big deal as long as you are Unity2020 or onwards: AFAIK it becomes automagically added at that point.

    Problems with Unity "tiny lite" built-in JSON:

    In general I highly suggest staying away from Unity's JSON "tiny lite" package. It's really not very capable at all and will silently fail on very common data structures, such as bare arrays, tuples, Dictionaries and Hashes and ALL properties.

    Instead grab Newtonsoft JSON .NET from the Unity Package Manager (Window -> Package Manager).

    If you want to avoid the Package Mangler's UI, just add this to your
    Packages/manifest.json
    file:

        "com.unity.nuget.newtonsoft-json": "3.0.2",


    The former asset store package is now deprecated, as you can see here:

    https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347

    Also, always be sure to leverage sites like:

    https://jsonlint.com
    https://json2csharp.com
    https://csharptojson.com/
     
    Last edited: Oct 9, 2023
    DungDajHjep likes this.
  11. Mauri

    Mauri

    Joined:
    Dec 9, 2010
    Posts:
    2,665
  12. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Thanks a lot! Looks like there's another one here:

    https://csharptojson.com/

    I shall update my notes accordingly. I really appreciate the heads-up.
     
  13. zuu1996

    zuu1996

    Joined:
    Jul 14, 2020
    Posts:
    2
    also you can use this instead of Dictionary
    Code (CSharp):
    1.     [Serializable]
    2.     public class SerializableDictionary<K, V> : Dictionary<K, V>, ISerializationCallbackReceiver
    3.     {
    4.         [SerializeField]
    5.         private List<K> m_Keys = new List<K>();
    6.  
    7.         [SerializeField]
    8.         private List<V> m_Values = new List<V>();
    9.  
    10.         public void OnBeforeSerialize()
    11.         {
    12.             m_Keys.Clear();
    13.             m_Values.Clear();
    14.             using Enumerator enumerator = GetEnumerator();
    15.             while (enumerator.MoveNext())
    16.             {
    17.                 KeyValuePair<K, V> current = enumerator.Current;
    18.                 m_Keys.Add(current.Key);
    19.                 m_Values.Add(current.Value);
    20.             }
    21.         }
    22.  
    23.         public void OnAfterDeserialize()
    24.         {
    25.             Clear();
    26.             for (int i = 0; i < m_Keys.Count; i++)
    27.             {
    28.                 Add(m_Keys[i], m_Values[i]);
    29.             }
    30.  
    31.             m_Keys.Clear();
    32.             m_Values.Clear();
    33.         }
    34.     }
     
    juliw21 likes this.