lxg95
lxg95

Reputation: 573

Get JSON Data in Unity (2D Array)

I am very new to Unity and C#. I am trying to load a JSON-string to Unity and everything works as expected, but when i want to load a 2D-Array it doesn't work at all.

I have either this...

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

...or this 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"
        }
    ]
}

i created a class QuizData for saving all the objects in it, looking like this

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

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

i can access the variables status and email easily myQuizDataObject.status or myQuizDataObject.email but i don't get anything with myQuizDataObject.questions[0] or something similar.

How do i do that?

Upvotes: 1

Views: 659

Answers (2)

derHugo
derHugo

Reputation: 90779

We don't see how exactly you parse that JSON string into the QuizData instance but I'ld assume you are using the JsonUtility.

Your c# data structure does not represent the structure you get. A cool tool for simply generate a c# layout of existing Json string is json2csharp. Only for Unity make sure to remove all the added {get; set;} which makes properties instead of fields which are not (de)serialized using the JsonUtility.

It would be something like

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

Then you would simply access e.g.

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

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

Depending on your needs instead of string you could also have a proper enum for correct_answer and your_answer like

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

and could even auto-fill a dictionary with it as also suggested in the other answer e.g. implementing the 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);
    }
}

Upvotes: 2

MomasVII
MomasVII

Reputation: 5081

I think myQuizDataObject.questions[0][A] (Guessing) would get a result, you can see the paring of data like "A": "Faro" which is the Key and the Value. But your data doesn't make much sense. Where did you get it?

It may be an array of Dictionary<string, string>

This seems to be what you need for the questions

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

Upvotes: 1

Related Questions