[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
. 지원 List
및 List
배열!
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.cs
Unity의 위키 에서 다운로드하십시오 .
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.ToJson
를 JsonUtility.ToJson
.
B . [Serializable]
직렬화중인 클래스의 맨 위에 추가하십시오 .
C . 클래스에서 속성을 제거합니다. 예를 들어, 변수, public string playerId { get; set; }
제거 { get; set; }
. Unity는 이것을 직렬화 할 수 없습니다.
역 직렬화 할 때 문제가 JsonUtility.FromJson
있습니까?
. 를 얻으면 Null
Json이 Json 배열이 아닌지 확인하십시오. 그렇다면 위의 도우미 클래스 JsonHelper.FromJson
를 JsonUtility.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);
}
}