在 Unity 中获取 JSON 数据(二维数组)

Get JSON Data in Unity (2D Array)

我对 Unity 和 C# 还很陌生。我正在尝试将 JSON-string 加载到 Unity 并且一切都按预期工作,但是当我想加载 2D-Array 时它根本不起作用。

我有这个...

{
    "status": 0, 
    "email": "exmpl@u", 
    "questions": [
        {
            "A": "Faro", 
            "C": "Oporto", 
            "B": "Lisbon", 
            "D": "Coimbra", 
            "question": "Which is the capital of Portugal?", 
            "your_answer": "", 
            "points": 10, 
            "correct_answer": "B"
        }, 
        {
            "A": "Seville", 
            "C": "Madrid", 
            "B": "Barcelona", 
            "D": "C\u00e1ceres", 
            "question": "Which is the capital of Spain?", 
            "your_answer": "", 
            "points": 15, 
            "correct_answer": "C"
        }, 
        {
            "A": "Gigon", 
            "C": "Cannes", 
            "B": "Marselle", 
            "D": "Paris", 
            "question": "Which is the capital of France?", 
            "your_answer": "", 
            "points": 20, 
            "correct_answer": "D"
        }
    ]
}

...或者这个字符串

{
    "status": 0, 
    "email": "exmpl@u", 
    "questions": [
        {
            "A": "Marcelo Rebelo de Sousa", 
            "C": "M\u00e1rio Soares", 
            "B": "Anibal Cavaco Silva", 
            "D": "Jorge Sampaio", 
            "question": "Which is the president of Portugal?",
            "your_answer": "", 
            "points": 10, 
            "correct_answer": "A"
        }, 
        {
            "A": "Fran\u00e7ois Miterrand", 
            "C": "Jacques Chirac", 
            "B": "Emmanuel Macron", 
            "D": "Nicolas Sarkozy", 
            "question": "Which is the president of France?", 
            "your_answer": "", 
            "points": 15, 
            "correct_answer": "B"
        }
    ]
}

我创建了一个 class QuizData 用于保存其中的所有对象,看起来像这样

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace QuizDataManager
{
    public class QuizData
    {
        public int status;
        public string email;
        public string[] questions;
    }
}

我可以轻松访问变量状态和电子邮件 myQuizDataObject.status 或 myQuizDataObject.email 但我没有得到任何 myQuizDataObject.questions[0] 或类似的东西。

我该怎么做?

我认为myQuizDataObject.questions[0][A] (Guessing)会得到一个结果,你可以看到像"A": "Faro"这样的数据配对,即Key和Value。但是你的数据没有多大意义。你从哪里弄来的?

可能是Dictionary<string, string>

的数组

好像是你需要的问题

{
    "status": 0, 
    "email": "exmpl@u", 
    "questions": [{
        "A": "Marcelo Rebelo de Sousa", 
        "C": "M\u00e1rio Soares", 
        "B": "Anibal Cavaco Silva", 
        "D": "Jorge Sampaio", 
        "question": "Which is the president of Portugal?", 
        "your_answer": "", 
        "points": 10, 
        "correct_answer": "A"
    }, {
        "A": "Fran\u00e7ois Miterrand", 
        "C": "Jacques Chirac", 
        "B": "Emmanuel Macron", 
        "D": "Nicolas Sarkozy", 
        "question": "Which is the president of France?", 
        "your_answer": "", 
        "points": 15, 
        "correct_answer": "B"
    }]
}

我们不知道您是如何将 JSON 字符串准确解析为 QuizData 实例的,但我假设您使用的是 JsonUtility.

您的 c# 数据结构不代表您获得的结构。用于简单地生成现有 Json 字符串的 c# 布局的一个很酷的工具是 json2csharp。仅对于 Unity,请确保删除所有添加的 {get; set;},这会生成属性而不是使用 JsonUtility.

未(反)序列化的字段

会是这样的

[Serializable]
public class QuizData
{
    public int status;
    public string email;
    public Question[] questions;
}

[Serializable]
public class Question
{
    public string A;
    public string C;
    public string B;
    public string D;

    public string question;
    public string your_amswer;
    public int points;
    public string correct_answer;
}

那么您只需访问例如

var myQuizDataObject = JsonUtility.FromJson<QuizData>(theJsonString);

var firstQuestion = myQuizDataObject.questions[0].question;
var answerA = myQuizDataObject.questions[0].A;
...

根据您的需要而不是 string,您还可以为 correct_answeryour_answer 提供适当的枚举,例如

public enum AnswerOption
{
    None,
    A,
    B,
    C,
    D
}

[Serializable]
public class Question
{
    public string A;
    public string C;
    public string B;
    public string D;

    public string question;
    public AnswerOption your_amswer;
    public int points;
    public AnswerOption correct_answer;
}

甚至可以 auto-fill 一本字典,正如其他答案中所建议的那样,例如实施 ISerializationCallbackReceiver interface

[Serializable]
public class Question : ISerializationCallbackReceiver
{
    public readonly Dictionary<AnswerOption, string>() answers;

    public string A;
    public string C;
    public string B;
    public string D;

    public string question;
    public AnswerOption your_amswer;
    public int points;
    public AnswerOption correct_answer;

    public void OnBeforeSerialize()
    {
        // do nothing but required by the interface
    }

    public void OnAfterDeserialize()
    {
        answers = new Dictionary<AnswerOption, string>(4);

        _myDictionary.Add(AnswerOption.A, A);
        _myDictionary.Add(AnswerOption.B, B);
        _myDictionary.Add(AnswerOption.C, C);
        _myDictionary.Add(AnswerOption.D, D);
    }
}