Serialize / Deserialize dictionary with unity serialization system, without using lists for keys and values

Hello,

The following class:

[System.Serializable]
public class Profile
{
    public string nick;
    public Dictionary<string, long> highScores; // <mapid, score>
}

should write, when serialized, jsons with a format like this:

{
    "nick" : "player1",
    "highScores" : {
        "mapid1" : 1234,
        "mapid2" : 2345,
        "mapidn" : 3456
    }
}

.

The second answer to this question addresses the issue, but for me it’s only a pretty good workaround, as output format is not ideal.

(for reference, this is the output obtained following the solution given):

{
    "nick" : "player1",
    "highScores" : {
        "keys" : ["mapid1", "mapid2", "mapidn"],
        "values" : [1234, 2345, 3456]
    }
}

.

I’ve tried to use dynamic programming to create class members on the go, as explained here, but I’m not able to import the needed packages (perhaps they are not supported in unity).

It would be great if it was possible to override Serialize/ToString and Deserialize/FromString methods. Is this possible? Any other idea?

Thanks in advance!

This is not possible with Unity’s JsonUtility. It’s a pure object mapper and only plays by the rules of Unity’s serialization system. Therefore it can’t serialize Dictionaries at all.

If you just want to ensure this Json format you could use my SimpleJSON framework.

You can create your own Serialize / Deserialize method like this:

[System.Serializable]
public class Profile
{
    public string nick;
    public Dictionary<string, long> highScores; // <mapid, score>
    pubic JSONNode Serialize()
    {
        var n = new JSONObject();
        n["nick"] = nick;
        var h = n["highScores"].AsObject;
        foreach(var v in highScores)
            h[v.Key] = v.Value;
        return n;
    }
    public void Deserialize(JSONNode aNode)
    {
        nick = aNode["nick"];
        highScores = new Dictionary<string, long>();
        foreach(var v in aNode["highScores"])
            highScores[v.Key] = v.Value;
    }
}

To get your Json text just do

    Profile profile;
    string text = profile.Serialize().ToString(3);

Note that the “3” is the space indention count. If you don’t pass an indention count it will create compact json without newline characters.

To deserialize just do something like:

    string text;
    Profile profile = new Profile();
    profile.Deserialize(JSON.Parse(text));