개념공부

JSON 기초 정리 (with Unity)

Cadi 2025. 3. 11. 02:16

JSON이란 ?

  • JavaScript Object Notation의 약자
  • 좀 더 쉽게 데이터를 교환하고 저장하기 위하여 만들어진 텍스트 기반의 데이터 교환 표준
  • 어떠한 프로그래밍 언어에서도 JSON 데이터를 읽고 사용할 수 있음( 파싱 라이브러리가 존재한다면 )
  • 네트워크 통신이나 설정 파일 저장 등 다양한 환경에서 널리 사용됨

특징

  • 자바스크립트 객체 표기법을 따름
    ( 중괄호 '{ }' 를 사용하여 객체를 정의하고, 그 안에 키(Key)와 값(Value) 쌍을 나열하는 방식)
  • 사람과 기계가 모두 읽기 편하도록 제작
  • 프로그래밍 언어와 운영 체제에 독립적

JSON 객체

  • JSON 객체는 중괄호 ( { } ) 로 둘러쌓아 표현
  • 쉼표를 사용하여 여러 프로퍼티를 포함할 수 있음

JSON 배열

  • JSON 배열은 대괄호 ( [ ] )로 둘러쌓아 표현
  • 쉼표를 사용하여 여러 JSON 데이터 포함 가능
{
  "name": "홍길동",
  "age": 25,
  "skills": ["C#", "Unity", "JSON"]
}

JSON 배열 각 요소는 쉼표( , ) 로 구분됨

JSON 타입

 

기본적으로 다음과 같은 기본 타입들을 제공

  • 숫자(number)
  • 문자열(string)
  • 불리언(boolean)
  • 객체(object)
  • 배열(array)
  • null

* JSON은 타입을 엄격하게 구분하지 않으며, 동적 형식 기반

ex )  "10"은 문자열, 10은 숫자  

직렬화(Serialization) 역직렬화(Deserialization) 

직렬화(Serialize)

  • Object 또는 Data를 다른 컴퓨터의 시스템에서도 사용할 수 있도록 바이트 스트림(stream of bytes) 형태로 연속전인(serial) 데이터로 변환하는 포맷 변환 기술

역직렬화(Deserialize)

  • 바이트로 변환된 데이터를 원래대로 Object 또는 Data로 변환하는 기술

Unity에서의 직렬화

  • 클래스/ 구조체(Custom) : [Serializable] 을 앞에 붙여서 가능
    명확하게 말하자면, 해당 클래스를 Unity의 직렬화 시스템에 등록/마킹(Attribute)  
  • 필드(Field) : public 혹은 [Serializable] private
  • 직렬화 가능 타입 : int, float, string, bool, Vector3, Color 등 유니티에서 지원하는 타입
  • 직렬화 불가 타입 : Dictionary, HashSet, delegate, interface 등 -> 커스텀 처리 필요
    마찬가지로 DateTime이나 Nullable<T> ( int?, bool?)도 JsonUtility에서는 직렬화 불고

 

 

 Unity에서 JSON을 다루는 방법

1. JsonUtility

  • 유니티에 기본 내장되어 있음
  • 빠르고 가벼움
  • 직렬화 대상은 반드시 class 또는 struct, [Serializable] 필요
  • Dictionary 지원 X, 복잡한 구조 처리가 어려움  

사용 예시

 

직렬화(객체-> JSON)

[System.Serializable]
public class PlayerData
{
    public string name;
    public int score;
}

PlayerData data = new PlayerData();
data.name = "Alice";
data.score = 100;

string json = JsonUtility.ToJson(data);
Debug.Log(json);  // {"name":"Alice","score":100}

 

역직렬화(JSON -> 객체)

string json = "{\"name\":\"Bob\",\"score\":150}";
PlayerData data = JsonUtility.FromJson<PlayerData>(json);
Debug.Log(data.name);  // "Bob"

 

2. Newtonsoft.Json

  • 외부 패키지 설치 필요
  • 강력하고 유연한 JSON 라이브러리
  • Dictionary, 리스트, 중첩 구조, LINQ  다양한 컨버터 지원
  • 용량이 크고 ,WebGL 빌드 시 주의 필요
using Newtonsoft.Json;

Dictionary<string, int> scores = new Dictionary<string, int>();
scores["Alice"] = 100;
scores["Bob"] = 200;

string json = JsonConvert.SerializeObject(scores);
Debug.Log(json);  // {"Alice":100,"Bob":200}

var parsed = JsonConvert.DeserializeObject<Dictionary<string, int>>(json);
Debug.Log(parsed["Bob"]); // 200

 

using문으로 Newtonsoft.Json 네임스페이스 사용,

Dictionary형도 변환 가능

 

public class GameData
{
    public string level;
    public List<PlayerData> players;
}

뿐만 아니라 이런 복잡한 클래스도 변환 가능하다.

 

 

 

JSON 관련 질문 (with GPT)

  •  Serializable이 직렬화라면, 왜 유니티 스크립트에서 [Serializable]을 하면 인스펙터 창에 보이는가 ?

[Serializable]을 붙이지 않으면, Unity의 Inspector와 Save 시스템은 해당 필드를 무시함

따라서 Unity는 해당 클래스의 필드를 저장도 안 하고, Inspector에서도 못 보여준다. 

반면, [Serializable]을 붙이면 Unity에서 내부적으로 해당 데이터를 바이트 단위로 변환/저장 할 수 있으므로

에디터에도 노출되고, 저장 시에도 저장될 수 있음.

 

=> Inspector에서 보이지 않을 때도 잘 작동하는데, 이는 무엇을 의미하는가 ?

 

Inspector 창에 보이지 않는 변수들, 즉 직렬화 되어서 유니티 직렬화 시스템에서 관리되지 않는 것들은

값이 저장 되지 않고( 씬 저장 시 휘발), 인스펙터에서 수정이 불가하고, Prefab이나 ScriptableObject에 저장되지 않을 뿐

기능은 여전히 돌아간다. 

 

유니티에서 직렬화

  • 바이트 스트림이란 정확히 무엇을 의미하는가 ? 

모든 데이터는 결국 0과 1로 구성된 연속된 바이트(8비트)들의 흐름(Stream)이다. 

( ex : int형은 4바이트 (32비트) 따라서 2의 32승까지의 범위만 표현 가능)

 

그래서 데이터를 주고 받을 때 결국 01010과 같은 형식으로 주고받게 되는데 , 이렇게 전송할 수 있도록 나열된 바이트 스트림으로 바꾸는 과정이 '직렬화'이다 .

  • JSONConverter, Custom Serializer은 무엇인가 ?

JsonConverter/CustomSerializer 는 복잡하거나 특수한 클래스 (Vector3, Color 등) 을 JSON에서 특정 방식으로 저장/로드

하고 싶을 때 사용하는 방법, 기본 JsonConverter를 상속받아 특수한 변환 규칙을 직접 정의할 수 있음

 

예시) 

public class CustomVector3Converter : JsonConverter<Vector3>
{
    public override void WriteJson(JsonWriter writer, Vector3 value, JsonSerializer serializer)
    {
        writer.WriteStartObject();
        writer.WritePropertyName("x"); writer.WriteValue(value.x);
        writer.WritePropertyName("y"); writer.WriteValue(value.y);
        writer.WritePropertyName("z"); writer.WriteValue(value.z);
        writer.WriteEndObject();
    }

    public override Vector3 ReadJson(JsonReader reader, Type objectType, Vector3 existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        return new Vector3((float)jo["x"], (float)jo["y"], (float)jo["z"]);
    }
}
  • ScriptableObject와 JSON의 장단점 차이와 , 용도 차이는 무엇인가 ?

ScriptableObject는 기본적으로 에디터, 유니티 asset파일로 관리하는 데이터이기 때문에 네트워크 전송에 비적합하다.

그래서 고정된 정보인 스탯, 아이템 등의 정보를 저장하는데 적합하고

JSON은 동적으로 데이터를 저장/로드 하면서 서버로 전송이 자유롭기 때문에 플레이어 저장 데이터는 JSON이 적합하다.

 

 

참고 사이트 : 

https://docs.unity3d.com/kr/2021.3/Manual/script-Serialization.html

 

스크립트 직렬화 - Unity 매뉴얼

직렬화는 데이터 구조 또는 게임 오브젝트 상태를 Unity가 보관하고 나중에 다시 복구할 수 있는 포맷으로 변환하는 자동 프로세스입니다.

docs.unity3d.com

https://inpa.tistory.com/entry/JSON-%F0%9F%93%91-JSON-%EA%B8%B0%EC%B4%88-%EC%A0%95%EB%A6%AC

 

📑 JSON 기초 문법 정리

JSON 이란? JSON은 JavaScript Object Notation의 약자입니다. JSON은 좀 더 쉽게 데이터를 교환하고 저장하기 위하여 만들어진 텍스트 기반의 데이터 교환 표준입니다. ​이러한 JSON은 XML의 대안으로서 좀

inpa.tistory.com

 

 


아니 그래서 초반에 이유를 못 찾고 헤맸던, 유니티 인스펙터 창에서 한 번 데이터를 변화시키면 스크립트 창에서 변수를 변화시켜도 무시하고 인스펙터 창의 데이터를 우선시하는 현상에 대한 단서를 이제야 찾았다.

유니티는 에디터(Inspector)에서 값을 한 번이라도 수정하면 그 값은 씬 저장 데이터나, 프리팹 데이터로 고정되기 때문에

이후에 스크립트에서 초기값을 바꾸더라도 이미 저장된 인스펙터 창의 값이 우선 값을 가지게 되는 것...

 

'개념공부' 카테고리의 다른 글

SocketIO 관련 정리  (0) 2025.03.12
Session, Cookie + 자동 로그인 기능  (0) 2025.03.06
UnityWebRequest  (0) 2025.03.05
Task, Async/Await  (0) 2025.02.22
생성자(Constructor)  (0) 2025.02.18