Десериализация Unity вложенного JSON - PullRequest
0 голосов
/ 11 апреля 2019

Я пытаюсь создать систему рекордов с использованием Firebase для проекта Unity. Для получения JSON я использую RESTCLIENT. Мне удалось загрузить результаты отлично, но их десериализация оказывается проблемой.

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;
    }
}

Идеальным решением будет следующий формат JSON:

{
    "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"
        }
    }
}

Я пытался использовать JsonUtility от unity, newtonsoft и моего собственного 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;
}

}

Я могу получить данные, когда есть только одна запись, но я не могу получить оценки, когда есть несколько имен пользователей.

1 Ответ

1 голос
/ 11 апреля 2019

Ваш json имеет фиксированное количество уровней и фиксированное количество пользователей. На самом деле вам потребуется такой объект для десериализации:

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;}
}

Предполагая, что ваше намерение состояло не только в том, чтобы иметь только 2 фиксированных уровня и 2 фиксированных пользователя, ваш json должен быть структурирован следующим образом (обратите внимание, что уровни - это массив, а оценки внутри уровня - это массивы):

{
    "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"
            }]
        }
    ]
}

Тогда ваши классы C # будут:

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>();
    }
}

Если вы действительно пытаетесь отслеживать только 2 фиксированных уровня с оценками для 2 фиксированных пользователей, ваш json должен работать с исходной структурой классов, которую я представил.

...