Program Tip

Unity에서 Json 및 Json 배열 직렬화 및 역 직렬화

programtip 2020. 10. 13. 19:06
반응형

Unity에서 Json 및 Json 배열 직렬화 및 역 직렬화


을 사용하여 PHP 파일에서 Unity로 보내는 항목 목록이 있습니다 WWW.

WWW.text외모가 좋아 :

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

어디 여분을 잘라 []으로부터 string. 을 사용하여 구문 분석을 시도 Boomlagoon.JSON하면 첫 번째 개체 만 검색됩니다. 나는에있는 것을 발견 deserialize()목록 및 MiniJSON을 가져 왔습니다.

그러나 나는 deserialize()이 목록에 대해 혼란 스럽습니다 . 모든 JSON 개체를 반복하고 데이터를 검색하고 싶습니다. C #을 사용하여 Unity에서 어떻게 할 수 있습니까?

내가 사용하는 수업은

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

트리밍 후 []MiniJSON을 사용하여 json을 구문 분석 할 수 있습니다. 그러나 그것은 첫 번째 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));
}

감사!


Unity는 5.3.3 업데이트 이후 API JsonUtility추가 했습니다 . 더 복잡한 작업을 수행하지 않는 한 모든 타사 라이브러리는 잊어 버리십시오. JsonUtility는 다른 Json 라이브러리보다 빠릅니다. Unity 5.3.3 버전 이상으로 업데이트 한 다음 아래 해결 방법을 시도해보세요.

JsonUtility경량 API입니다. 단순 유형 만 지원됩니다. 사전과 같은 컬렉션 지원 하지 않습니다 . 한 가지 예외는 List. 지원 ListList배열!

a를 직렬화해야 Dictionary하거나 단순한 데이터 유형을 단순히 직렬화 및 역 직렬화하는 것 이외의 작업을 수행 해야하는 경우 타사 API를 사용하십시오. 그렇지 않으면 계속 읽으십시오.

직렬화 할 예제 클래스 :

[Serializable]
public class Player
{
    public string playerId;
    public string playerLoc;
    public string playerNick;
}

1. 하나의 데이터 개체 (비 배열 JSON)

파트 A 직렬화 :

public static string ToJson(object obj);메서드 를 사용하여 Json으로 직렬화 합니다 .

Player playerInstance = new Player();
playerInstance.playerId = "8484239823";
playerInstance.playerLoc = "Powai";
playerInstance.playerNick = "Random Nick";

//Convert to Jason
string playerToJason = JsonUtility.ToJson(playerInstance);
Debug.Log(playerToJason);

출력 :

{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}

파트 B 직렬화 :

public static string ToJson(object obj, bool prettyPrint);메서드 오버로드 를 사용하여 Json으로 직렬화 합니다 . 간단히 전달 true받는 JsonUtility.ToJson기능은 데이터를 포맷합니다. 아래 출력을 위의 출력과 비교하십시오.

Player playerInstance = new Player();
playerInstance.playerId = "8484239823";
playerInstance.playerLoc = "Powai";
playerInstance.playerNick = "Random Nick";

//Convert to Jason
string playerToJason = JsonUtility.ToJson(playerInstance, true);
Debug.Log(playerToJason);

출력 :

{
    "playerId": "8484239823",
    "playerLoc": "Powai",
    "playerNick": "Random Nick"
}

파트 A 직렬화 해제 :

public static T FromJson(string json);메서드 오버로드를 사용하여 json을 역 직렬화합니다 .

string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = JsonUtility.FromJson<Player>(jsonString);
Debug.Log(player.playerLoc);

파트 B 역 직렬화 :

public static object FromJson(string json, Type type);메서드 오버로드를 사용하여 json을 역 직렬화합니다 .

string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player));
Debug.Log(player.playerLoc);

파트 C 역 직렬화 :

public static void FromJsonOverwrite(string json, object objectToOverwrite);메서드로 json을 역 직렬화 합니다 . JsonUtility.FromJsonOverwrite이 사용 되면 역 직렬화하려는 해당 개체의 새 인스턴스가 생성되지 않습니다. 전달한 인스턴스를 재사용하고 값을 덮어 씁니다.

이것은 효율적이며 가능하면 사용해야합니다.

Player playerInstance;
void Start()
{
    //Must create instance once
    playerInstance = new Player();
    deserialize();
}

void deserialize()
{
    string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";

    //Overwrite the values in the existing class instance "playerInstance". Less memory Allocation
    JsonUtility.FromJsonOverwrite(jsonString, playerInstance);
    Debug.Log(playerInstance.playerLoc);
}

2. 다중 데이터 (ARRAY JSON)

Json에는 여러 데이터 개체가 포함되어 있습니다. 예를 들어 playerId 이상 나타났습니다 . 유니티의는 JsonUtility여전히 새로운하지만 당신이 사용할 수있는 배열을 지원하지 않습니다 도우미 얻기 위해이 사람에서 클래스를 배열 작업 JsonUtility.

라는 클래스를 만듭니다 JsonHelper. 아래에서 직접 JsonHelper를 복사하십시오.

public static class JsonHelper
{
    public static T[] FromJson<T>(string json)
    {
        Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
        return wrapper.Items;
    }

    public static string ToJson<T>(T[] array)
    {
        Wrapper<T> wrapper = new Wrapper<T>();
        wrapper.Items = array;
        return JsonUtility.ToJson(wrapper);
    }

    public static string ToJson<T>(T[] array, bool prettyPrint)
    {
        Wrapper<T> wrapper = new Wrapper<T>();
        wrapper.Items = array;
        return JsonUtility.ToJson(wrapper, prettyPrint);
    }

    [Serializable]
    private class Wrapper<T>
    {
        public T[] Items;
    }
}

Json 배열 직렬화 :

Player[] playerInstance = new Player[2];

playerInstance[0] = new Player();
playerInstance[0].playerId = "8484239823";
playerInstance[0].playerLoc = "Powai";
playerInstance[0].playerNick = "Random Nick";

playerInstance[1] = new Player();
playerInstance[1].playerId = "512343283";
playerInstance[1].playerLoc = "User2";
playerInstance[1].playerNick = "Rand Nick 2";

//Convert to Jason
string playerToJason = JsonHelper.ToJson(playerInstance, true);
Debug.Log(playerToJason);

출력 :

{
    "Items": [
        {
            "playerId": "8484239823",
            "playerLoc": "Powai",
            "playerNick": "Random Nick"
        },
        {
            "playerId": "512343283",
            "playerLoc": "User2",
            "playerNick": "Rand Nick 2"
        }
    ]
}

Json 배열 역 직렬화 :

string jsonString = "{\r\n    \"Items\": [\r\n        {\r\n            \"playerId\": \"8484239823\",\r\n            \"playerLoc\": \"Powai\",\r\n            \"playerNick\": \"Random Nick\"\r\n        },\r\n        {\r\n            \"playerId\": \"512343283\",\r\n            \"playerLoc\": \"User2\",\r\n            \"playerNick\": \"Rand Nick 2\"\r\n        }\r\n    ]\r\n}";

Player[] player = JsonHelper.FromJson<Player>(jsonString);
Debug.Log(player[0].playerLoc);
Debug.Log(player[1].playerLoc);

출력 :

Powai

사용자 2


이것이 서버의 Json 배열이고 직접 생성하지 않은 경우 :

{"Items":수신 된 문자열 앞에 추가 한 다음 }끝에 추가해야 할 수도 있습니다 .

이를 위해 간단한 기능을 만들었습니다.

string fixJson(string value)
{
    value = "{\"Items\":" + value + "}";
    return value;
}

그런 다음 사용할 수 있습니다.

string jsonString = fixJson(yourJsonFromServer);
Player[] player = JsonHelper.FromJson<Player>(jsonString);

3. 클래스없이 json 문자열을 역 직렬화하고 숫자 속성을 사용하여 Json을 역 직렬화합니다.

이것은 숫자 또는 숫자 속성으로 시작하는 Json입니다.

예를 들면 :

{ 
"USD" : {"15m" : 1740.01, "last" : 1740.01, "buy" : 1740.01, "sell" : 1744.74, "symbol" : "$"}, 

"ISK" : {"15m" : 179479.11, "last" : 179479.11, "buy" : 179479.11, "sell" : 179967, "symbol" : "kr"},

"NZD" : {"15m" : 2522.84, "last" : 2522.84, "buy" : 2522.84, "sell" : 2529.69, "symbol" : "$"}
}

Unity JsonUtility는 "15m"속성이 숫자로 시작하기 때문에이를 지원하지 않습니다. 클래스 변수는 정수로 시작할 수 없습니다.

SimpleJSON.csUnity의 위키 에서 다운로드하십시오 .

USD의 "15m"속성을 얻으려면 :

var N = JSON.Parse(yourJsonString);
string price = N["USD"]["15m"].Value;
Debug.Log(price);

ISK의 "15m"속성을 얻으려면 :

var N = JSON.Parse(yourJsonString);
string price = N["ISK"]["15m"].Value;
Debug.Log(price);

NZD의 "15m"속성을 얻으려면 :

var N = JSON.Parse(yourJsonString);
string price = N["NZD"]["15m"].Value;
Debug.Log(price);

숫자로 시작하지 않는 나머지 Json 속성은 Unity의 JsonUtility에서 처리 할 수 ​​있습니다.


4. JsonUtility 문제 해결 :

직렬화 할 때 문제가 JsonUtility.ToJson있습니까?

빈 문자열 또는 " {}"를 JsonUtility.ToJson?

. 클래스가 배열이 아닌지 확인하십시오. 그렇다면 위의 도우미 클래스 JsonHelper.ToJsonJsonUtility.ToJson.

B . [Serializable]직렬화중인 클래스의 맨 위에 추가하십시오 .

C . 클래스에서 속성을 제거합니다. 예를 들어, 변수, public string playerId { get; set; } 제거 { get; set; } . Unity는 이것을 직렬화 할 수 없습니다.

역 직렬화 할 때 문제가 JsonUtility.FromJson있습니까?

. 를 얻으면 NullJson이 Json 배열이 아닌지 확인하십시오. 그렇다면 위의 도우미 클래스 JsonHelper.FromJsonJsonUtility.FromJson.

B . NullReferenceException역 직렬화하는 동안 얻으면 [Serializable]클래스 맨 위에 추가하십시오 .

C.Any other problems, verify that your json is valid. Go to this site here and paste the json. It should show you if the json is valid. It should also generate the proper class with the Json. Just make sure to remove remove { get; set; } from each variable and also add [Serializable] to the top of each class generated.


Newtonsoft.Json:

If for some reason Newtonsoft.Json must be used then check out the forked version for Unity here. Note that you may experience crash if certain feature is used. Be careful.


To answer your question:

Your original data is

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

Add {"Items": in front of it then add } at the end of it.

Code to do this:

serviceData = "{\"Items\":" + serviceData + "}";

Now you have:

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

To serialize the multiple data from php as arrays, you can now do

public player[] playerInstance;
playerInstance = JsonHelper.FromJson<player>(serviceData);

playerInstance[0] is your first data

playerInstance[1] is your second data

playerInstance[2] is your third data

or data inside the class with playerInstance[0].playerLoc, playerInstance[1].playerLoc, playerInstance[2].playerLoc ......

You can use playerInstance.Length to check the length before accessing it.

NOTE: Remove { get; set; } from the player class. If you have { get; set; }, it won't work. Unity's JsonUtility does NOT work with class members that are defined as properties.


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


you have to add [System.Serializable] to PlayerItem class ,like this:

using System;
[System.Serializable]
public class PlayerItem   {
    public string playerId;
    public string playerLoc;
    public string playerNick;
}

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

Don't trim the [] and you should be fine. [] identify a JSON array which is exactly what you require to be able to iterate its elements.


Like @Maximiliangerhardt said, MiniJson do not have the capability to deserialize properly. I used JsonFx and works like a charm. Works with the []

player[] p = JsonReader.Deserialize<player[]>(serviceData);
Debug.Log(p[0].playerId +" "+ p[0].playerLoc+"--"+ p[1].playerId + " " + p[1].playerLoc+"--"+ p[2].playerId + " " + p[2].playerLoc);

참고URL : https://stackoverflow.com/questions/36239705/serialize-and-deserialize-json-and-json-array-in-unity

반응형