Unity/개념 및 분석

Unity JSON 기본 개념 + 사용[JsonUtility + JSON .NET For Unity(newtonsoft.json) + LitJson + MiniJson] 아는 거 다 써버려

최애뎡 2021. 6. 25. 11:15
728x90
반응형

[ * 필자 Unity 버전 == 2020.3.6f1 ]

 

JSON(JavaScript Object Notation)

- JavaScript에서 객체를 만들 때 사용하는 표현식

* { "ID" : 1, "HP" : 100 } <- {} 객체 ([ "a", "b", "c" ] <- [] 배열)

- 경량의 데이터 형식(Key, Value)으로 데이터를 저장, 불러올 때 사용하기 용이

 

[{
		"ID": 0,
		"kill_Count": 10,
		"Hit_Count": 100
	},
	{
		"ID": 1,
		"kill_Count": 5,
		"Hit_Count": 1,
		"Items": [
			"sword", "shield"
		]
	}
]

 

이런 식으로 JSON 작성

* 비슷한 형식으로 XML이 존재함

http://tcpschool.com/json/json_intro_xml

- 주관적으로 XML의 가독성도 크게 나쁘지 않음(사이즈가 커지면 다르겠댜 - 아 아니ㅑ 사이즈 커지면 보기 힘들어)

- 속도는 JSON이 더 빠름 (문자열을 전송받고 해당 문자열을 바로 파싱함)

* 파싱 - https://ko.wikipedia.org/wiki/%EA%B5%AC%EB%AC%B8_%EB%B6%84%EC%84%9D

- XML은 배열을 사용할 수 없음

 

1. JsonUtility

- Unity에 내장된 JSON Class *JSON 라이브러리의 모든 기능을 지원하지 않고 최소한의 기능을 제공

[일반 클래스, 구조체 지원]

https://docs.unity3d.com/ScriptReference/JsonUtility.html

 

Unity - Scripting API: JsonUtility

Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close

docs.unity3d.com

doc에서 간단한 내용 확인

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class Player_Data
{
    public int kill_Count;
    public int Hit_Count;

    public Player_Data(int killcount, int hitcount)
    {
        kill_Count = killcount;
        Hit_Count = hitcount;
    }

    public void getKillCount()
    {
        Debug.Log("killcount: " + kill_Count);
    }

    public void getHitCount()
    {
        Debug.Log("hitcount: " + Hit_Count);
    }
}

public class JsonTest_JsonUtility : MonoBehaviour
{
    private void Start()
    {
        Player_Data playerData = new Player_Data(10, 1);
        string json_Data = ObjectToJson(playerData); //Json 형식으로
        Debug.Log(json_Data);

        Player_Data playrData_1 = JsonToObject<Player_Data>(json_Data); //Json 형식 받아오는
        playrData_1.getKillCount();
        playrData_1.getHitCount();

		//json파일로 저장
        string path = Path.Combine(Application.dataPath + "/playerData.json");
        File.WriteAllText(path, json_Data);

		//json파일도 물론 받아올 수 있음
        string getJSON = File.ReadAllText(Application.dataPath + "/playerData.json");
        Player_Data playerData_2 = JsonToObject<Player_Data>(getJSON);        
        playerData_2.getKillCount();
        playerData_2.getHitCount();        
    }

    string ObjectToJson(object obj)
    {
    	//ToJson의 2번째 매개변수(prettyprint)는 생성될 Json의 형식을 이쁘게 보이게 해주기 위함
        return JsonUtility.ToJson(obj, true);
    }

    T JsonToObject<T>(string JsonData) where T : class
    {
        return JsonUtility.FromJson<T>(JsonData);
    }
}

 

이런 식으로 사용

 

2. JSON .NET For Unity (newtonsoft.json)

https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347

 

JSON .NET For Unity | 입출력 관리 | Unity Asset Store

Get the JSON .NET For Unity package from parentElement, LLC and speed up your game development process. Find this & other 입출력 관리 options on the Unity Asset Store.

assetstore.unity.com

doc의 경우 임포트하면 친절하게 PDF로 남겨있음

 

* 예전에 이걸 사용하다 에디터상에서만 작동이 돼서 크게 낭패를 본 기억이 있다. 지금은 될란가 모르겠....

[JSON 라이브러리는 널리고 널렸기에 나 같음 이거 안 씀]

라고 했는데 해보니까 모바일에서 되는디..?

된다야

음.. 현재 2020.3.0f1을 사용 중인데 말이 많긴 하다 2020보다 하위 버전은 뭐 또 안된다 하고 어후

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using System.IO;

class ExampleData
{
    public int Kill_Count;
    public int Hit_Count;

    public ExampleData(int kill_Count, int hit_Count)
    {
        Kill_Count = kill_Count;
        Hit_Count = hit_Count;
    }
}

public class JsonTest_newtonsoft : MonoBehaviour
{
    private void Start()
    {
        ExampleData ex = new ExampleData(10, 1);

        //ToJson
        string json_Data = ObjectToJson(ex);
        Debug.Log(json_Data);

        //GetJson
        ExampleData getjson_Data = JsonToObject<ExampleData>(json_Data);
        Debug.Log(getjson_Data.Kill_Count + " " + getjson_Data.Hit_Count);

        //List, Dictionary등 여러 형식도 가능
        List<ExampleData> list_ex = new List<ExampleData>();
        list_ex.Add(new ExampleData(10, 1));
        list_ex.Add(new ExampleData(100, 5));
        string json_Data_list = ObjectToJson(list_ex);
        Debug.Log(json_Data_list);

        List<string> list_str = new List<string>() { "index_0", "index_1" };
        string json_Data_liststr = ObjectToJson(list_str);
        Debug.Log(json_Data_liststr);

        Dictionary<int, ExampleData> dic_ex = new Dictionary<int, ExampleData>();
        dic_ex.Add(0, new ExampleData(1, 10));
        dic_ex.Add(1, new ExampleData(10, 50));
        string json_Data_dictionary = ObjectToJson(dic_ex);
        Debug.Log(json_Data_dictionary);

        Dictionary<int, string> dic_intstr = new Dictionary<int, string>();
        dic_intstr.Add(0, "index_0");
        dic_intstr.Add(1, "index_1");
        string json_Data_dicIntStr = ObjectToJson(dic_intstr);
        Debug.Log(json_Data_dicIntStr);

        //Json으로 저장, 읽기
        string path = Path.Combine(Application.dataPath + "/newtonsoftData.json");
        File.WriteAllText(path, json_Data_dicIntStr);

        string getJson = File.ReadAllText(path);
        Dictionary<int, string> getJson_Dic = JsonToObject<Dictionary<int, string>>(getJson);
        Debug.Log(getJson_Dic[0] + " " + getJson_Dic[1]);
    }

    string ObjectToJson(object data)
    {
        return JsonConvert.SerializeObject(data);
    }

    T JsonToObject<T>(string JsonData)
    {
        return JsonConvert.DeserializeObject<T>(JsonData);
    }
}

 

뭐 하튼 이런 식으로 사용한다.

 

3. LitJson 

https://litjson.net/

 

LitJSON - Home

What is LitJSON? A .Net library to handle conversions from and to JSON (JavaScript Object Notation) strings. LitJSON is written in C#, and it’s intended to be small, fast and easy to use. It's quick and lean, without external dependencies. Just a few cla

litjson.net

상단 메뉴 Source -> GIthub에서 다운 -> 폴더에서 src 안에 LitJson폴더만 가져와도 됨

* API가 친절하게 상단 메뉴에 있음, test폴더에 사용 예시도 친절하게 있음

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LitJson;
using System.IO;

class LitJson_Data
{
    public int kill_Count;
    public int Hit_Count;

    public LitJson_Data(int killcount, int hitcount)
    {
        kill_Count = killcount;
        Hit_Count = hitcount;
    }

    public void getKillCount()
    {
        Debug.Log("killcount: " + kill_Count);
    }

    public void getHitCount()
    {
        Debug.Log("hitcount: " + Hit_Count);
    }
}

public class JsonTest_LitJson : MonoBehaviour
{
    private void Start()
    {
        LitJson_Data litJsonData = new LitJson_Data(10, 1);
        string json_Data = ObjectToJson(litJsonData); //Json 형식으로
        Debug.Log(json_Data);

        //json파일로 저장
        string path = Path.Combine(Application.dataPath + "/litJsonData.json");
        File.WriteAllText(path, json_Data);

        //json파일 불러오고
        string getJSON = File.ReadAllText(path);
        JsonData JsonData_ = JsonToObject(getJSON); //json은 JsonData형식으로 불러와짐 -> 파싱해야함

        LitJson_Data litJsonData_1 = new LitJson_Data(0, 0) ;
        print(litJsonData_1.kill_Count + " " + litJsonData_1.Hit_Count);
        litJsonData_1.kill_Count = (int)JsonData_[0];
        litJsonData_1.Hit_Count = (int)JsonData_[1];
        print(litJsonData_1.kill_Count + " " + litJsonData_1.Hit_Count);        
    }

    string ObjectToJson(object obj)
    {
        return JsonMapper.ToJson(obj);
    }

    JsonData JsonToObject(string JsonData)
    {
        return JsonMapper.ToObject(JsonData);
    }
}

 

음 그런데 지금 Json이 너무 짧다.

만약에 위 상황에서 JSON이

 

{
	"PlayerData": [{
			"ID": 0,
			"name": "aaa",
			"HP": 100,
			"MP": 200
		},
		{
			"ID": 1,
			"name": "bbb",
			"HP": 200,
			"MP": 50
		}
	],
	"MonsterData": [{
			"ID": 100,
			"name": "slime",
			"HP": 100,
			"MP": 200
		},
		{
			"ID": 100,
			"name": "skeleton",
			"HP": 200,
			"MP": 50
		}
	]
}

 

이런 형식일 때 JsonData jsonData로 받아왔다 치면

jsonData["PlayerData"][0]["name"]은 "aaa"가 되는 거고

jsonData["MonsterData"][1]["name"]은 "skeleton"이 되는 걸 알아야 함..

* JsonMapper, ToJson, ToObject, JsonData 의 정의를 보면(f12) 구조를 볼 수 있다.

 

4. MiniJson

https://gist.github.com/darktable/1411710

 

Unity3D: MiniJSON Decodes and encodes simple JSON strings. Not intended for use with massive JSON strings, probably < 32k prefe

Unity3D: MiniJSON Decodes and encodes simple JSON strings. Not intended for use with massive JSON strings, probably < 32k preferred. Handy for parsing JSON from inside Unity3d. - MiniJSON.cs

gist.github.com

무슨 코드에 사용 예시가 바로 있다. 좋다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MiniJSON;

public class JsonTest_MiniJson : MonoBehaviour
{
    private void Start()
    {
        var jsonString = "{ \"array\": [1.44,2,3], " +
                        "\"object\": {\"key1\":\"value1\", \"key2\":256}, " +
                        "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " +
                        "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " +
                        "\"int\": 65536, " +
                        "\"float\": 3.1415926, " +
                        "\"bool\": true, " +
                        "\"null\": null }";

        var dict = Json.Deserialize(jsonString) as Dictionary<string, object>;

        Debug.Log("deserialized: " + dict.GetType());
        Debug.Log("dict['array'][0]: " + ((List<object>)dict["array"])[0]);
        Debug.Log("dict['string']: " + (string)dict["string"]);
        Debug.Log("dict['float']: " + (double)dict["float"]); // floats come out as doubles
        Debug.Log("dict['int']: " + (long)dict["int"]); // ints come out as longs
        Debug.Log("dict['unicode']: " + (string)dict["unicode"]);

        var str = Json.Serialize(dict);

        Debug.Log("serialized: " + str);
    }
}

 

예시 부분만 따온..

끝났따 사실..

다줬네..

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using MiniJSON;

public class JsonTest_MiniJson : MonoBehaviour
{
    private void Start()
    {
        //Dictionary
        Dictionary<string, int> list_ex = new Dictionary<string, int>();
        list_ex.Add("index_0", 0);
        list_ex.Add("index_1", 1);

        string json_Data = ObjectToJson(list_ex);
        Debug.Log(json_Data);

        string path = Path.Combine(Application.dataPath + "/miniJsonData.json");
        File.WriteAllText(path, json_Data);

        string getJSON = File.ReadAllText(Application.dataPath + "/miniJsonData.json");

        var list_ex_1 = JsonToObject(getJSON) as Dictionary<string, object>;
        Debug.Log(list_ex_1["index_1"]);

        //List
        List<int> list_ex_2 = new List<int>();
        list_ex_2.Add(0);
        list_ex_2.Add(1);

        string json_Data_1 = ObjectToJson(list_ex_2);
        Debug.Log(json_Data_1);

        string path_1 = Path.Combine(Application.dataPath + "/miniJsonDatalist.json");
        File.WriteAllText(path_1, json_Data_1);

        string getJSON_1 = File.ReadAllText(Application.dataPath + "/miniJsonDatalist.json");

        var list_ex_3 = JsonToObject(getJSON_1) as List<object>;
        Debug.Log(list_ex_3[0]);
    }

    string ObjectToJson(object obj)
    {
        return Json.Serialize(obj);
    }

    object JsonToObject(string JsonData)
    {
        return Json.Deserialize(JsonData);
    }
}

 

그래도 일단! 이렇게 사용 가능한 부분

-> MiniJSON.cs를 보면 Dictionary, List를 지원하는것을 볼 수 있음

 

 

 

* JSON 작업할 때 유용

1. Exel to JSON

http://shancarter.github.io/mr-data-converter/

 

Mr. Data Converter

 

shancarter.github.io

2. JSON 검사

https://jsonlint.com/

 

The JSON Validator

JSONLint is the free online validator and reformatter tool for JSON, a lightweight data-interchange format.

jsonlint.com

반응형