简体   繁体   中英

Unity Deserialization of nested JSON

I am trying to create a high score system using firebase for a unity project. To retrieve the JSON I am using RESTCLIENT. I have managed to upload the scores fine but deserializing them is proving to be a problem.

JSON = "{"UserName1":{"Name":"UN1","ScoreVal":"99/100"},"UserName2":{"Name":"UN2","ScoreVal":"100/100"}}"

[Serializable]
public class RootObject
{
    public Score score { get; set; }
}

[Serializable]
public class Score
{
    public string Name;
    public string ScoreVal;

    public Score(string name, string scoreVal)
    {
        this.Name = name;
        this.ScoreVal = scoreVal;
    }
}

The ideal solution would follow this JSON format:

{
    "Level1":{
        "User1":{
            "Name":"User1",
            "Score":"100/100"
            },
        "User2":{
            "Name":"User2",
            "Score":"100/100"
            }
        },
    "Level2": {
        "User1": {
            "Name":"User1",
            "ScoreVal":"99/100"
        },
        "User2": {
            "Name":"User2",
            "ScoreVal":"100/100"
        }
    }
}

I have tried using JsonUtility from unity, newtonsoft and my own jsonhelper:

public static class JsonHelper2
{
public static T[] FromJson<T>(string json)
{
    Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
    return wrapper.Items;
}

public static string ToJson<T>(T[] array)
{
    Wrapper<T> wrapper = new Wrapper<T>();
    wrapper.Items = array;
    return JsonUtility.ToJson(wrapper);
}

public static string ToJson<T>(T[] array, bool prettyPrint)
{
    Wrapper<T> wrapper = new Wrapper<T>();
    wrapper.Items = array;
    return JsonUtility.ToJson(wrapper, prettyPrint);
}

[Serializable]
private class Wrapper<T>
{
    public T[] Items;
}

}

I can retreive data when there is only one entry but I am unable to get scores when there are multiple usernames.

Your json has a fixed number of levels and a fixed number of users. You'd actually require an object like this to deserialize it:

public class Scores
{
    public Users Level1 {get;set;}
    public Users Level2 {get;set;}
}

public class Users
{
    public User User1 {get;set;}
    public User User2 {get;set;}
}

public class User
{
    public string Name {get;set;}
    public string Score {get;set;}
}

Assuming your intention was not to only have 2 fixed levels and 2 fixed users, your json should be structured like this (note that levels are an array and the scores within the level are arrays):

{
    "levels": [{
            "name": "Level 1",
            "scores": [{
                "user": "User1",
                "score": "8/10"
            }, {
                "user": "User2",
                "score": "7/10"
            }]
        },
        {
            "name": "Level 2",
            "scores": [{
                "user": "User1",
                "score": "9/10"
            }, {
                "user": "User3",
                "score": "6/10"
            }]
        }
    ]
}

Then your C# classes will be:

public class Score
{
    public string user {get;set;}
    public string score {get;set;}
}

public class Level
{
    public string name {get;set;}
    public IList<Score> scores {get;}

    public Level()
    {
        scores = new List<Score>();
    }
}

public class RootObject
{
    public IList<Level> levels {get;}

    public RootObject()
    {
        levels = new List<Level>();
    }
}

If in fact you really are only trying to track 2 fixed levels with the scores for 2 fixed users, your json should work with the initial class structure I presented.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM