【问题标题】:Unity Deserialization of nested JSON嵌套 JSON 的 Unity 反序列化
【发布时间】:2019-04-11 16:19:28
【问题描述】:

我正在尝试使用 firebase 为一个统一项目创建一个高分系统。要检索我使用 RESTCLIENT 的 JSON。我已经设法很好地上传了分数,但反序列化它们被证明是一个问题。

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

我尝试过使用来自 unity、newtonsoft 和我自己的 jsonhelper 的 JsonUtility:

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

}

当只有一个条目时我可以检索数据,但当有多个用户名时我无法获得分数。

【问题讨论】:

    标签: c# json unity3d deserialization json-deserialization


    【解决方案1】:

    您的 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 应该可以使用我提供的初始类结构。

    【讨论】:

    • 您好科林,感谢您的回答。我遇到的问题是我没有固定数量的用户。级别固定为 10,所以这不是什么大问题,因为我可以按照您上面的描述进行操作。知道如何使它适用于未指定数量的用户吗?
    • 我在答案中输入的 json 结构允许“无限”数量的级别和每个级别的无限数量的高分。注意level 对象数组,它们本身包含HighScore 对象数组。您对 json 的总体了解程度如何?
    • 您可能会发现json2csharp.com 很有帮助。它会从一个 json 样本为你生成一个 C# 类。
    • 啊,是的,我只是设法实现它。谢谢!这是我第一次使用 json。
    • @ColinYoung 感谢 json2csharp 提示 - 节省时间
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 2022-01-22
    • 1970-01-01
    • 2017-03-10
    相关资源
    最近更新 更多