Json

Json이란..?

JavaScript Object Notation의 약어로 모든 값이 직렬화가 가능한 키-값의 쌍으로 이루어진 데이터를 텍스트를 사용하는 개방형 표준 포맷이다.

과거에는 CSV형식을 자주 사용했다고 했을 때 요즘엔 클래스형태가 그대로 표현되는 Json을 많이 사용하는 것 같다.

세이브나 로드, 게임에서 사용되는 대사 등을 엑셀로 작성하고 json으로 연결하여 많이 사용하며 인간이 쉽게 읽을 수 있는 데이터 형태이기 때문에 유용하다.

{
    "name": "fkdl",
    "x": 2,
    "y": 7
}

유니티에서 Json을 사용한다고 했을 때 가장 많이 사용하는게 JsonUtillty클래스이다.

다른 방식의 Json .NET For Unity가 있지만 속도 차이가 많이 남 이외에도 Mini, Lit 등등 라이브러리가 다양하게 존재함

JsonUtillty

Unity오브젝트를 Json으로 포맷하거나 Json형태를 유니티 오브젝트형태로 바꿀 수 있다.

Unity에 내장된 클래스이기 때문에 최소한의 기능들만 제공한다.

마찬가지로 다양한 기능들을 사용하고 싶다면 다른 라이브러리를 추가로 받아서 사용해야 한다.

JsonUtility.ToJson

public static string ToJson(object obj, bool prettyPrint)

  • 여기서 prettyPrint는 좀더 읽기 쉽게 로드 해준다.
  • obj는 object형식이기 때문에 직렬화 된 클래스라면 다 읽을 수 있는 것을 알 수 있다.

ToJson은 말 그대로 유니티 오브젝트를 Json파일로 만드는 메서드이다.

Json포맷으로 변환하기 이전에 직렬화가 된 클래스만 변환이 가능하다.

[System.Serializable]
public class MyBox
{
    public string name;
    public int x;
    public int y;
}
public class JsonTest : MonoBehaviour
{
    void Start()
    {
        MyBox a = new MyBox();
        a.name = "fkdl";
        a.x = 2;
        a.y = 7;
        
        string box = JsonUtility.ToJson(a, true);

        print(box);
    }
}

생성된 객체를 Json포맷으로 box라는 문자열을 만들었다.

직접 실행해보면 아래와 같은 결과를 얻는다.

{
    "name": "fkdl",
    "x": 2,
    "y": 7
}

JsonUtility.FromJson

public static object FromJson(string json, System.Type type)

  • json: 문자열로 된 Json형식의 포맷 파일이 필요하다
  • public static T FromJson<T>(string json) => (T) JsonUtility.FromJson(json, typeof (T));제네릭을 사용하기 때문에 무명함수를 통해 type를 뽑아낸다.
public class JsonTest : MonoBehaviour
{
    void Start()
    {
        MyBox a = new MyBox();

        a.name = "fkdl";
        a.x = 2;
        a.y = 4;
        
        string box = JsonUtility.ToJson(a, true);

        var mybox = JsonUtility.FromJson<MyBox>(box);

        print(mybox);
    }
}

FromJson은 반대로 데이터를 읽어오는 과정이기 때문에 앞서 file을 문자열로 읽어오는 과정이 필요하다.

지금은 ToJson으로 이미 파일을 문자열로 포맷을 진행했지만 File클래스나 Resources클래스를 통해 읽어와야 한다.

간단하게 기능만 봐도 다양하게 필요한 데이터를 저장하거나 기획쪽에 데이터를 전달하기에 용이해 보인다..

JsonUtility 주의사항

  1. 배열로 된 클래스는 읽지 못하기 때문에 한번 더 매핑을 통해 전달해야 한다.

JsonUtility가 덩치가 큰 클래스를 읽지 못한다는 말이 있어서 JsonHelper클래스를 사용해서 고친다는 말이 많지만 그게 아닌 배열을 읽지 못하는 문제이다.

void Start()
{
    MyBox[] a = new MyBox[5];

    string box = JsonUtility.ToJson(a, true);

    print(box);
}

{} // 출력값

만약 box가 여러개인 즉, 배열을 Json으로 만들어야 한다면 직렬화된 새로운 클래스에 box배열을 담아야 함

[Serializable]
public class MyBoxs
{
    public MyBox[] boxs;
}
public class JsonTest : MonoBehaviour
{
    void Start()
    {
        MyBoxs a = new MyBoxs();

        a.boxs = new MyBox[5];
        for (int i = 0; i < 5; i++)
        {
            a.boxs[i] = new MyBox();
            a.boxs[i].name = "box_" + i;
        }

        string box = JsonUtility.ToJson(a, true);

        print(box);
    }
}

출력값

{
    "boxs": [
        {
            "name": "box_0",
            "x": 0,
            "y": 0
        },
        {
            "name": "box_1",
            "x": 0,
            "y": 0
        },
        {
            "name": "box_2",
            "x": 0,
            "y": 0
        },
        {
            "name": "box_3",
            "x": 0,
            "y": 0
        },
        {
            "name": "box_4",
            "x": 0,
            "y": 0
        }
    ]
}
  1. 빌드하는 경우 경로 지정 문제

파일을 읽거나 저장하는 경우 File.WriteAllText메서드를 통해 Application.dataPath에서 읽거나 저장하게 되는데

빌드 이후에 게임에서 읽지 못하는 오류가 있다.

따라서 유니티 지정폴더인 Resources에 저장, 불러오기를 사용해야 한다.

Resources.Load<TextAsset>("Json/" + fileName);
  • fileName에는 확장자를 붙이지 않는다. (box.txt -> box)
  • 경로 또한 리소스폴더 내부가 root로 생각하고 적어야 한다.

참고링크

태그: ,

카테고리:

업데이트:

댓글남기기