Version: 2021.2
언어: 한국어
스크립트 직렬화 오류
스크립트 컴파일

JSON 직렬화

JsonUtility 클래스를 사용하여 Unity 오브젝트를 JSON 포맷으로 상호 전환할 수 있습니다. 예를 들어 JSON 직렬화를 사용하여 웹 서비스와 상호작용하거나, 데이터를 텍스트 기반 포맷으로 쉽게 패킹하거나 언패킹하십시오.

JSON 직렬화는 “구조화된” JSON 개념을 사용합니다. 즉 JSON 데이터에 저장하려는 변수를 설명하는 클래스 또는 구조를 만들어야 합니다. 예를 들면 다음과 같습니다.

[Serializable]
public class MyClass
{
    public int level;
    public float timeElapsed;
    public string playerName;
}

세 가지 변수(level, timeElapsed, playerName)가 들어 있는 플레인 C# 클래스를 정의하고 Serializable 속성으로 표시하여 JSON 시리얼라이저와 연동되도록 만듭니다. 예를 들어 클래스의 인스턴스를 만들기 위해 다음을 사용할 수 있습니다.

MyClass myObject = new MyClass();
myObject.level = 1;
myObject.timeElapsed = 47.5f;
myObject.playerName = "Dr Charles Francis";

그런 다음 JsonUtility.ToJson 메서드를 사용하여 JSON 포맷으로 직렬화(전환)하십시오.

string json = JsonUtility.ToJson(myObject);
// json now contains: '{"level":1,"timeElapsed":47.5,"playerName":"Dr Charles Francis"}'

JSON을 다시 오브젝트로 전환하려면 JsonUtility.FromJson을 사용하십시오.

myObject = JsonUtility.FromJson<MyClass>(json);

그러면 MyClass의 새 인스턴스가 생성되고 JSON 데이터를 사용하여 인스턴스의 값이 설정됩니다. JSON 데이터에 MyClass의 필드와 매핑되지 않는 값이 있으면 시리얼라이저가 해당 값을 무시합니다. JSON 데이터에 MyClass 필드에 누락된 값이 있으면 시리얼라이저는 해당 필드에 구성된 값을 반환된 오브젝트에 그대로 유지합니다.

JSON 시리얼라이저는 현재 비구조화된 JSON 사용을 지원하지 않습니다. 즉 JSON을 임의의 키-값 쌍 트리로 탐색하고 편집할 수 없습니다. 비구조화된 JSON을 사용해야 하는 경우 모든 기능을 제공하는 JSON 라이브러리를 찾아야 합니다.

JSON으로 오브젝트 덮어쓰기

기존 오브젝트에 대해 JSON 데이터를 역직렬화하여 기존 데이터를 모두 덮어쓸 수도 있습니다.

JsonUtility.FromJsonOverwrite(json, myObject);

JSON 데이터에 필드에 대한 값이 없으면 시리얼라이저는 해당 필드의 값을 변경하지 않습니다. 이 방식을 통해 이전에 만든 오브젝트를 재사용하여 할당을 최소한으로 유지하고, 의도적으로 오브젝트를 필드의 작은 부분 집합만 포함된 JSON으로 덮어써서 “패치”할 수도 있습니다.

경고: JSON 시리얼라이저 API는 MonoBehaviourScriptableObject 서브 클래스뿐만 아니라 일반 구조체와 클래스도 지원합니다. 하지만 JSON을 MonoBehaviour 또는 ScriptableObject의 서브 클래스를 역직렬화하는 경우에는 FromJsonOverwrite 메서드를 사용해야 합니다. FromJson을 사용하면 지원되지 않는 동작이므로 Unity에서 예외가 발생합니다.

지원되는 타입

JSON 시리얼라이저 API는 MonoBehaviour 서브클래스, ScriptableObject 서브 클래스, 또는 [Serializable] 속성이 있는 일반 클래스/구조체를 지원합니다. 오브젝트를 스탠다드 Unity 시리얼라이저에 전달하여 처리할 경우 인스펙터에서와 동일한 규칙과 제한 사항이 적용됩니다. Unity는 필드만 직렬화하고 Dictionary<> 같은 타입은 지원되지 않습니다.

Unity에서는 기본형 또는 배열 등과 같은 다른 타입을 직접 API로 전달할 수 없습니다. 이러한 타입을 전환해야 하는 경우 class 또는 struct로 래핑하십시오.

에디터에만 EditorJsonUtility라는 병렬 API가 있습니다. 이 API는 UnityEngine.Object에서 파생된 오브젝트를 JSON와 상호 직렬화하도록 해줍니다. 이렇게 하면 오브젝트의 YAML 표현과 동일한 데이터가 포함된 JSON이 생성됩니다.

성능

벤치마크 테스트에 따르면 JsonUtility는 일부 경우 더 적은 기능을 제공함에도 불구하고 인기 있는 .NET JSON 솔루션보다 훨씬 더 빠른 성능을 자랑합니다.

가비지 컬렉션(GC)은 최소의 메모리를 사용합니다.

  • ToJson이 반환된 문자열에만 GC 메모리를 할당합니다.
  • FromJson이 반환된 오브젝트와 필요한 서브 오브젝트에만 GC 메모리를 할당합니다. 예를 들어 배열이 포함된 오브젝트를 역직렬화하면 Unity가 GC 메모리를 배열에 할당합니다.
  • FromJsonOverwrite는 필요한 경우에만 작성된 필드(예: 문자열 또는 배열)에 GC 메모리를 할당합니다. 즉 JSON으로 덮어써지는 모든 필드가 값 타입이면 Unity는 GC 메모리를 할당하지 않습니다.

백그라운드 스레드에서 JsonUtility API를 사용할 수 있습니다. 하지만 다른 멀티스레드 코드와 마찬가지로, 다른 스레드에서 오브젝트를 직렬화/역직렬화하는 동안에는 해당 오브젝트를 수정하거나 액세스하지 않도록 주의하십시오.

ToJson()의 출력 제어

ToJson 메서드는 JSON 출력을 보기 좋게 출력하는 기능을 지원합니다. 이 기능은 기본적으로 꺼져 있지만, true를 두 번째 파라미터로 전달하여 켤 수 있습니다.

[NonSerialized] 속성을 사용하여 필드를 출력에서 생략할 수 있습니다.

알 수 없는 타입의 FromJson() 사용

오브젝트 타입을 미리 알 수 없는 경우 JSON을 “common” 필드가 포함된 클래스나 구조체로 역직렬화한 다음 해당 필드의 값을 사용하여 원하는 실제 타입을 정한 후 해당 타입으로 다시 역직렬화할 수 있습니다.

스크립트 직렬화 오류
스크립트 컴파일