Serialize and Deserialize Json and Json Array in Unity

Viewed 241278

I have a list of items send from a PHP file to unity using WWW.

The WWW.text looks like:

[
    {
        "playerId": "1",
        "playerLoc": "Powai"
    },
    {
        "playerId": "2",
        "playerLoc": "Andheri"
    },
    {
        "playerId": "3",
        "playerLoc": "Churchgate"
    }
]

Where I trim the extra [] from the string. When I try to parse it using Boomlagoon.JSON, only the first object is retrieved. I found out that I have to deserialize() the list and have imported MiniJSON.

But I am confused how to deserialize() this list. I want to loop through every JSON object and retrieve data. How can I do this in Unity using C#?

The class I am using is

public class player
{
    public string playerId { get; set; }
    public string playerLoc { get; set; }
    public string playerNick { get; set; }
}

After trimming the [] I am able to parse the json using MiniJSON. But it is returning only the first KeyValuePair.

IDictionary<string, object> players = Json.Deserialize(serviceData) as IDictionary<string, object>;

foreach (KeyValuePair<string, object> kvp in players)
{
    Debug.Log(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value));
}

Thanks!

9 Answers

Assume you got a JSON like this

[
    {
        "type": "qrcode",
        "symbol": [
            {
                "seq": 0,
                "data": "HelloWorld9887725216",
                "error": null
            }
        ]
    }
]

To parse the above JSON in unity, you can create JSON model like this.

[System.Serializable]
public class QrCodeResult
{
    public QRCodeData[] result;
}

[System.Serializable]
public class Symbol
{
    public int seq;
    public string data;
    public string error;
}

[System.Serializable]
public class QRCodeData
{
    public string type;
    public Symbol[] symbol;
}

And then simply parse in the following manner...

var myObject = JsonUtility.FromJson<QrCodeResult>("{\"result\":" + jsonString.ToString() + "}");

Now you can modify the JSON/CODE according to your need. https://docs.unity3d.com/Manual/JSONSerialization.html

Unity <= 2019

Narottam Goyal had a good idea of wrapping the array in a json object, and then deserializing into a struct. The following uses Generics to solve this for arrays of all type, as opposed to making a new class everytime.

[System.Serializable]
private struct JsonArrayWrapper<T> {
    public T wrap_result;
}

public static T ParseJsonArray<T>(string json) {
    var temp = JsonUtility.FromJson<JsonArrayWrapper<T>>("{\"wrap_result\":" + json + "}");
    return temp.wrap_result;
}

It can be used in the following way:

string[] options = ParseJsonArray<string[]>(someArrayOfStringsJson);

Unity 2020

In Unity 2020 there is an official newtonsoft package which is a far better json library.

To Read JSON File, refer this simple example

Your JSON File (StreamingAssets/Player.json)

{
    "Name": "MyName",
    "Level": 4
}

C# Script

public class Demo
{
    public void ReadJSON()
    {
        string path = Application.streamingAssetsPath + "/Player.json";
        string JSONString = File.ReadAllText(path);
        Player player = JsonUtility.FromJson<Player>(JSONString);
        Debug.Log(player.Name);
    }
}

[System.Serializable]
public class Player
{
    public string Name;
    public int Level;
}

You can use Newtonsoft.Json just add Newtonsoft.dll to your project and use below script

using System;
using Newtonsoft.Json;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{

    [Serializable]
    public class Person
    {
        public string id;
        public string name;
    }
    public Person[] person;

    private void Start()
    {
       var myjson = JsonConvert.SerializeObject(person);

        print(myjson);

    }
}

enter image description here

another solution is using JsonHelper

using System;
using Newtonsoft.Json;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{

    [Serializable]
    public class Person
    {
        public string id;
        public string name;
    }
    public Person[] person;

    private void Start()
    {
        var myjson = JsonHelper.ToJson(person);

        print(myjson);

    }
}

enter image description here

IF you are using Vector3 this is what i did

1- I create a class Name it Player

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class Player
{
    public Vector3[] Position;

}

2- then i call it like this

if ( _ispressed == true)
        {
            Player playerInstance = new Player();
            playerInstance.Position = newPos;
            string jsonData = JsonUtility.ToJson(playerInstance);

            reference.Child("Position" + Random.Range(0, 1000000)).SetRawJsonValueAsync(jsonData);
            Debug.Log(jsonData);
            _ispressed = false;
        }

3- and this is the result

"Position":[ {"x":-2.8567452430725099,"y":-2.4323320388793947,"z":0.0}]}

Related