Oscar Oscar - 6 months ago 112
JSON Question

Unity5.3 Json how to construct a complex Json object using unities new Json utility

I have a 2 part question.
First i am trying to write the code that can write a json file that looks like this.

{
"Restaurants":[
{
"Name" : "Asami",
"ID" : 0,
"Plates" :
[
{
"title" : "Plate1 ",
"color" : "Red ",
"price" : 5
},
{
"title" : "Plate1 ",
"color" : "Green ",
"price" : 6
},
{
"title" : "Plate1 ",
"color" : "Blue ",
"price" : 7
},
{
"title" : "Plate1 ",
"color" : "Yellow ",
"price" : 8
}
]
}
]
}


The code i have sofar is this.

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

public class UnityJsonTest : MonoBehaviour {

public string aName;
public int aId = 0;
public string aPlate1, aPlate2;
public Color aColor1, aColor2;
public int aPrice1, aPrice2;

// Use this for initialization
void Start ()
{
Restaurant1 rester = new Restaurant1();

rester.MainName = aName;
rester.Character1[0].Name = aName;

string rjson = JsonUtility.ToJson(rester);

File.WriteAllText(Application.dataPath + "/player.json", rjson.ToString());

MyClass myObject = new MyClass();
myObject.level = 1;
myObject.playerName = "Dr Charles Francis";

string json = JsonUtility.ToJson(myObject);

File.WriteAllText(Application.dataPath + "/test.json", json.ToString());
}

// Update is called once per frame
void Update () {

}
}

[Serializable]
public class MyClass
{
public int level;
public string playerName;
}

[Serializable]
public class Restaurant1
{
public string MainName;
public Character1[] Character1;
}

[Serializable]
public class Character1
{
public string Name;
public int Id;
public Plate1[] Plate1;
}

[Serializable]
public class Plate1
{
public string Title;
public Color Color;
public int Price;
}


if you look at the MyClass myObject = new MyClass(); and the 2 lines after that. it works perfectly. That is the example from the Unity Docs.

but when i tried to use that and make it abit more complex i seem to have missed something.

in the line

Restaurant1 rester = new Restaurant1();

rester.MainName = aName; //This works.

rester.Character1[0].Name = aName;


// This does NOT work. in unity i get a "NullReferenceException: Object reference not set to an instance of an object"
and i have absolutely no idea why. What am i doing wrong here?

The second part of my question is what is the best way to write this thing so that i can set the number of "Plates" objects to a user defined amount? and then i would assume i need a for loop to fill in each of the plate objects?

I have searched far and wide for examples on this but all the examples are done like the myClass. very simple with no explanation on how to build something more complex.

If you guys could help that would be amazing :)

Thanks in advance.

Answer

You are so close. You are only missing two steps. rester.Character1 is a class and at the-same time, an array.

For it to work, you must declare the size of the array. Let's use 4 for this example:

rester.Character1 = new Character1[4];

Then you have to initialize each Character1 class in the element by creating a new instance of each of them:

 for (int i = 0; i < rester.Character1.Length; i++)
 {
     rester.Character1[i] = new Character1();
 }

Done! Now, you can call rester.Character1[0].Name = aName; without any problems. Arrays are trick but you must undertand these steps.

The second part of my question is what is the best way to write this thing so that i can set the number of "Plates" objects to a user defined amount? and then i would assume i need a for loop to fill in each of the plate objects?

Accessing Plates is tricky because that's an array inside another array. You need multiple for loops to easily do that. You can get Input with from the user with UI/InputField then use that to create number of Plates.

public InputField plateAmount;

//Declare size of each plate array. Get the amount of plates from the InputField/Player then convert it into int with Convert.ToInt32.

for (int i = 0; i < rester.Character1.Length; i++)
{
    rester.Character1[i].Plate1 = new Plate1[Convert.ToInt32(plateAmount.text)];
} 

Now create instance of each plate like we did for the Character1 class but this one requires multiple for loops which is also called Nested Loop due to array that is inside another array.

//Create new Instance of Plate1 classes
for (int i = 0; i < rester.Character1.Length; i++)
{
    for (int j = 0; j < rester.Character1[i].Plate1.Length; j++)
    {
        rester.Character1[i].Plate1[j] = new Plate1();
    }
}