So my question is two fold, first I have behaviour I don't understand and its due to me misunderstanding something about Json. So given the first example below I get what I want.
{
"data":{
"stats":{
"kills":0,
"gamesPlayed":30,
"shotsFired":30
}
},
"other":1
}
code:
JsonData jsonData = JsonMapper.ToObject (jsonString);
JsonData entries = jsonData["data"]["stats"];
m_kills = int.Parse(entries["kills"].ToString());
Debug.log(m_kills);
ouput
"0"
However when I use the same logic behind the code for this next json I get an error. so why is it when using the following Json and code
{
"data":{
"otherInfo":2,
"scoreboard":[
{
"player":"bob",
"score":57,
"pdata":{
"a":40,
"b":20
}
},
{
"player":"joe",
"score":32,
"pdata":{
"a":20,
"b":13
}
}
],
"otherInfo2":5
}
}
code
JsonData jsonData = JsonMapper.ToObject (jsonString);
JsonData entries = jsonData["data"];
m_info = int.Parse(entries["otherinfo"].ToString());
Debug.log(m_info);
I get
KeyNotFoundException: The given key was not present in the dictionary. System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <567df3e0919241ba98db88bec4c6696f>:0)
what is wrong within ?
JsonData entries = jsonData["data"];
m_info = int.Parse(entries["otherinfo"].ToString());
As for the 2nd part, 1st part is just so I can understand it better. My end goal is to get access to score for each player(beyond bob and joe want it to be expandable) and then also grab the pdata...so guess the question is 3 fold but help on any of these 3 would be greatly appreciated!
thanks
You should create a data model for your json. After that you can convert your json string into a valid object to reach your necessary property.
// the data models based on your json string
public class Pdata {
public int a { get; set; }
public int b { get; set; }
}
public class Scoreboard {
public string player { get; set; }
public int score { get; set; }
public Pdata pdata { get; set; }
}
public class Data {
public int otherInfo { get; set; }
public List<Scoreboard> scoreboard { get; set; }
public int otherInfo2 { get; set; }
}
public class Root {
public Data data { get; set; }
}
// code
Root root = JsonConvert.DeserializeObject<Root>(yourJsonString);
int otherInfo = root.data.otherInfo;
You can easily create your models at https://json2csharp.com/
It took me a while to spot as well but your error seems to be a typo!
In the json it is "otherInfo":2 but your are trying to access entries["otherinfo"].
In general you should rather implement according data structure in c# (json2csharp helps)
[Serializable]
public class Pdata
{
public int a;
public int b;
}
[Serializable]
public class Player
{
public string player;
public int score;
public Pdata pdata;
}
[Serializable]
public class Data
{
public int otherInfo;
public List<Player> scoreboard;
public int otherInfo2;
}
[Serializable]
public class Root
{
public Data data;
}
And then use JsonUtility.FromJson
var root = JsonUtility.FromJson<Root>(jsonString);
Debug.Log($"otherInfo: {root.data.otherInfo}");
foreach(var player in root.data.scoreboard)
{
Debug.Log($"Name: {player.player}, Score: {player.score}, A: {player.pdata.a}");
}
For your current data structure I would not recommend to struggle around with third-party libraries, the JsonUtility is fine here.
However, the deserialization of the Unity built-in JsonUtility is quite limited (see Unity - Script Serialization).
If it gets more complex and you want to use e.g. Dictionaries in the future then you will have to use something else like e.g. Newtonsoft .NET JSON.
Then it would be
var root = JsonConvert.DeserializeObject<Root>(jsonString);
...
You are missing '{' at the beginning and '}' at the end of your JSON.