본문 바로가기
Study/개념 정리

[Study] JSON과 직렬화

by chobbo 2024. 7. 22.

확인 문제

public class SomeClass : MonoBehaviour
{
    [SerializeField] private int intValue = 2;
    
    private void Start()
    {
	Debug.Log(intValue);
    }
}

 

1. 인스펙터에서 intValue의 값을 3으로 변경하고, intValue 앞에 선언된 [SerializeField] 제거 후 Debug.Log(intValue);의 출력 결과 

-> 2

intValue가 더 이상 직렬화되지 않으므로 스크립트 컴파일 시 2가 출력된다.

 

 

2. 인스펙터에서 intValue의 값을 3으로 변경하고, intValue 앞에 [HideInInspector]를 추가 후 

Debug.Log(intValue);의 출력 결과 

-> 3

[HideInInspector]를 사용하여 intValue가 직렬화되지만 인스펙터에서 표시되지 않기 때문에 

스크립트 컴파일 시 3가 출력된다.

 

 

 

 

 

CSV/JSON 등 데이터 저장 포맷에 대해 설명하고, 활용에 적절한 상황을 설명

CSV

number, name, age
1. 정은지, 99

 

- 쉼표를 기준으로 항목을 구분하여 데이터를 저장한다.

- 데이터 오염에 취약하고 데이터의 크기가 매우 작다

- 2차원 표 형식의 데이터와 같이 데이터 양이 복잡하지 않고 변화가 많지 않은 빠른 읽기 & 쓰기가 필요한 경우 적합하다.

 

JSON

{
    "people": [
        {
            "name": "정은지",
            "age": 99,
        },
    ]
}

 

- Key & Value 쌍으로 데이터를 표현

- 최근 가장 많이 사용된다. 모든 프로그래밍 언어에서 JSON형식 지원.

- 주석을 사용하지 못한다

- 복잡한 데이터 구조나 계층적 데이터를 다루는 데에 적합하다.

 

 

XML

<people>
    <name>정은지</name>
    <score>99</score>
</user>

 

- 트리 계층 구조를 가진다.

- 태그와 속성으로 인해 파일 크기가 커질 수 있다.

 

 


특정 데이터를 JSON으로 활용하기 위해 해야하는 작업? 

특정 데이터를 JSON으로 활용하기 위해선 데이터를 직렬화, 역직렬화 해야한다.

 

직렬화

객체를 저장 가능한 형식으로 변환하는 과정이 직렬화이다.

데이터를 저장할 때 사용한다.

 

1. 직렬화 할 데이터의 구조를 클래스 혹은 구조체로 선언. 이때 이 커스텀 클래스는 정적이 아니어야 한다.

2. 해당 클래스(구조체)에 [Serializable] 속성을 붙여 직렬화가 가능하게 한다.

[Serializable]
public class Practice
{
    public int Name;
    public int Age;
}

 

3. 클래스 (구조체) 를 선언하고 값을 초기화

Practice p = new Practice();
p.Name = "정은지";
p.Age = 99;

 

 

4. 클래스(구조체)를 Json 포맷의 문자열로 생성

string pToJson = JsonUtility.ToJson(p);

 

 

 

역직렬화

저장된 데이터를 다시 객체로 복원하는 과정이 역직렬화이다. 데이터를 불러올 때 사용한다.

 

1. Json 포멧의 문자열 데이터와 동일한 구조의 클래스의 인스턴스를 선언

2. Json 문자열 데이터를 해당 클래스의 구조로 역직렬화

p = JsonUtility.FromJson<Practice>(pToJson);

 

 


Unity에서 필드를 직렬화하는 방법

 

Unity에서는 다음과 같은 필드 데이터들을 직렬화 할 수 있다.

- public or [SerializeField] 속성이 붙어있는 필드 
- 정적(static), 상수(const), 읽기 전용(readonly), 추상클래스가 아닌 필드
- 기본 데이터 형식(int, float, double, bool, string 등)
- 열거형(Enum) 타입 (32 바이트 이하)
- 고정 크기 버퍼
- Unity 빌트인 타입(Vector2, Vector3 등과 같이 유니티가 제공하는 기능)
- Serializable 속성이 있는 커스텀 구조체 or 클래스
- UnityEngine.Object에서 파생된 오브젝트에 대한 레퍼런스
   -> 객체에 대한 참조 (GameObject, Component, ScriptableObject 등)
- 위에서 언급한 필드 타입의 배열 & List< T >

 

필드를 직렬화하면 Unity Inspector 내에서 필드 확인이 가능하다. 

 

Unity에서 필드를 직렬화 하는 방법은 다음과 같다.

 

1. [SerializeField] 속성을 사용

[SerializeField] private int num;

 

2. Public 필드는 자동으로 직렬화된다.

public int num;

 

3. 클래스나 구조체에 [Serializable] 속성을 사용

 

4. [HideInInspector] 속성을 사용 (인스펙터에서 필드를 숨기면서 직렬화)

[HideInInspector] private int num;

 

5. [SerializeReference]를 사용한 참조 기반의 직렬화

using System;
using UnityEngine;

public class SerializeReferencePolymorphismExample : MonoBehaviour
{	
    // 직렬화 할 기본 클래스
    [Serializable]
    public class Base
    {
        public int m_Data = 1;
    }

    // Base 클래스를 상속
    [Serializable]
    public class Apple : Base
    {
        public string m_Description = "Ripe";
    }

    // Base 클래스를 상속
    [Serializable]
    public class Orange : Base
    {
        public bool m_IsRound = true;
    }

    // m_Item, m_Item2는 Base 타입이지만 실제로는 Apple과 Orange 인스턴스를 참조
    // 유니티 2019.3 버전부터 사용 가능
    // 다형성 유지 가능
    [SerializeReference]
    public Base m_Item = new Apple();

    [SerializeReference]
    public Base m_Item2 = new Orange();

    // SerializeReference를 사용하지 않은 예제
    public Apple m_MyApple = new Apple();
}

 

위 예제를 보면 [SerializeReference] 속성을 사용하여 참조된 객체의 실제 타입(Apple 또는 Orange)을 저장하고, 이를 인스펙터에서 관리할 수 있게 하고 있다.

 

6. 프로퍼티를 활용한 직렬화

[field:SerializeField]

 

직렬화 하지 않기 위해 [NonSerialized] 속성을 사용할 수도 있다.

 

 

 

'Study > 개념 정리' 카테고리의 다른 글

[Study] 게임수학  (0) 2024.07.24
[Study] 멀티스레드 & GPU  (0) 2024.07.23
[Study] Graph와 길찾기  (0) 2024.07.19
[Study] Tree  (0) 2024.07.18
[Study] 최적화  (0) 2024.07.17