[c#] 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 JSON
string playerToJson = JsonUtility.ToJson(playerInstance);
Debug.Log(playerToJson);

출력 :

{"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 JSON
string playerToJson = JsonUtility.ToJson(playerInstance, true);
Debug.Log(playerToJson);

출력 :

{
    "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 JSON
string playerToJson = JsonHelper.ToJson(playerInstance, true);
Debug.Log(playerToJson);

출력 :

{
    "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. 기타 문제는 json이 유효한지 확인하십시오. 여기이 사이트로 이동 하여 json을 붙여 넣으십시오. json이 유효한지 표시해야합니다. 또한 Json으로 적절한 클래스를 생성해야합니다. 각 변수에서 제거를 제거 { get; set; } 하고 [Serializable]생성 된 각 클래스의 맨 위에 추가하십시오 .


Newtonsoft.Json :

어떤 이유로 Newtonsoft.Json을 사용해야 한다면 여기 에서 Unity 용 포크 버전을 확인 하세요 . 특정 기능을 사용하면 충돌이 발생할 수 있습니다. 조심해.


질문에 답하려면 :

원래 데이터는

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

추가 {"Items":프런트 는 다음의 추가 } 상기 그것의.

이를 수행하는 코드 :

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

이제 다음이 있습니다.

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

PHP 의 여러 데이터를 배열직렬화 하려면 이제 다음을 수행 할 수 있습니다.

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

playerInstance[0] 당신의 첫 번째 데이터입니다

playerInstance[1] 두 번째 데이터입니다

playerInstance[2] 세 번째 데이터입니다

이나와 클래스 내부 데이터 playerInstance[0].playerLoc, playerInstance[1].playerLoc, playerInstance[2].playerLoc

playerInstance.Length액세스하기 전에 길이를 확인하는 데 사용할 수 있습니다 .

참고 : 클래스 에서 제거하십시오 . 가있는 경우 작동하지 않습니다. Unity 는 속성 으로 정의 된 클래스 멤버와 작동 하지 않습니다 .{ get; set; }player{ get; set; }JsonUtility


답변

다음과 같은 JSON이 있다고 가정합니다.

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

위의 JSON을 Unity로 구문 분석하려면 다음과 같이 JSON 모델을 생성 할 수 있습니다.

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

그리고 다음과 같은 방식으로 간단히 구문 분석합니다.

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

이제 필요에 따라 JSON / CODE를 수정할 수 있습니다.
https://docs.unity3d.com/Manual/JSONSerialization.html


답변

다음 과 같이 클래스 에 추가 [System.Serializable]해야 PlayerItem합니다.

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


답변

트림하지 마십시오 []. 그러면 괜찮을 것입니다. []요소를 반복 할 수 있도록 정확히 필요한 JSON 배열을 식별하십시오.


답변

@Maximiliangerhardt가 말했듯이 MiniJson에는 제대로 역 직렬화 할 수있는 기능이 없습니다. 나는 JsonFx를 사용하고 매력처럼 작동합니다. 함께 작동[]

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


답변

JSON 파일을 읽으려면이 간단한 예제를 참조하십시오.

JSON 파일 (StreamingAssets / Player.json)

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

C # 스크립트

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


답변

당신이 사용할 수있는 Newtonsoft.Json단지 추가 Newtonsoft.dll프로젝트에 스크립트 아래 사용

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

    }
}

여기에 이미지 설명 입력

또 다른 해결책은 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);

    }
}

여기에 이미지 설명 입력