🔥 Serialization (직렬화) 개요
Serialization이란 객체 데이터를 바이트 스트림으로 변환하여 저장하거나 전송할 수 있도록 하는 과정
주 목적은 필요할 때 다시 개체로 만들 수 있도록 개체의 상태를 저장하는 것
반대로 Deserialization은 저장된 바이트 데이터를 다시 객체로 변환하는 과정입니다.

🔥 JSON, XML, YAML
일반적으로 많이 사용하는 데이터 직렬화 포맷들
1️⃣ JSON (JavaScript Object Notation)
✔️ 특징
✅ 가벼운 텍스트 기반 포맷
✅ 사람이 읽고 쓰기 쉬우며, 기계가 빠르게 처리 가능
✅ 대부분의 프로그래밍 언어에서 지원 (C#, Python, JavaScript 등)
✅ 키-값 쌍의 구조 (Dictionary, Object와 유사)
✔️ 예제
{
"name": "John",
"age": 30,
"skills": ["C#", "Unity", "Python"],
"isDeveloper": true
}
✔️ 장점
✅ 가볍고 속도가 빠름
✅ 대부분의 언어에서 지원
✅ API 및 데이터 전송에 적합 (REST API, WebSockets 등)
❌ 단점
❌ 주석 지원이 안됨
❌ XML이나 YAML보다 덜 유연함
2️⃣ XML (eXtensible Markup Language)
✔️ 특징
✅ 데이터 구조를 계층적으로 표현 (HTML과 유사)
✅ 사람이 읽을 수 있지만, JSON보다 길이가 김
✅ 다양한 도메인에서 사용 (문서 저장, 설정 파일, 웹 서비스 등)
✅ <태그>를 이용한 구조화된 데이터 표현
✔️ 예제
<Person>
<Name>John</Name>
<Age>30</Age>
<Skills>
<Skill>C#</Skill>
<Skill>Unity</Skill>
<Skill>Python</Skill>
</Skills>
<IsDeveloper>true</IsDeveloper>
</Person>
✔️ 장점
✅ 데이터 구조가 명확함
✅ 주석 사용 가능 (<!– 주석 –>)
✅ 다양한 데이터 타입을 표현하기 적합
❌ 단점
❌ JSON보다 크기가 크고, 가독성이 떨어짐
❌ 파싱 속도가 느림
3️⃣ YAML (YAML Ain’t Markup Language)
✔️ 특징
✅ JSON과 유사하지만 더 간결한 문법을 가짐
✅ 들여쓰기를 이용한 계층 구조 (Python과 유사)
✅ 설정 파일에서 많이 사용 (Docker, Kubernetes, Unity Config 등)
✔️ 예제
name: John age: 30 skills: - C# - Unity - Python isDeveloper: true
✔️ 장점
✅ 사람이 읽기 쉬운 직관적인 문법
✅ JSON보다 간결하여 가독성이 좋음
✅ 주석 (#) 사용 가능
❌ 단점
❌ 들여쓰기 실수로 인한 오류 발생 가능
❌ 파싱 속도가 JSON보다 느림

https://unity.com/kr/blog/engine-platform/understanding-unitys-serialization-language-yaml
🔎 비교 정리
Unity에서는 JSON (JsonUtility, Newtonsoft.Json)이 가장 많이 사용되며, YAML은 Unity의 설정 파일 (.yml)에서 많이 활용됩니다.
| 형식 | 문법 | 가독성 | 속도 | 사용 사례 |
|---|---|---|---|---|
| JSON | { "key": "value" } | 좋음 | 빠름 ✅ | API, 데이터 저장 |
| XML | <tag>value</tag> | 중간 | 느림 ❌ | 문서 저장, 설정 파일 |
| YAML | key: value (들여쓰기) | 매우 좋음 ✅ | 중간 | 설정 파일, DevOps |

🔥Unity에서의 스크립트 직렬화 (Serialization in Unity)
1️⃣ Unity에서 직렬화가 중요한 이유
Unity는 Inspector 창에서 데이터를 유지하거나 저장 시스템(예: PlayerPrefs, JSON, Binary 파일 등)에 데이터를 저장하기 위해 직렬화를 활용합니다.
✅ 씬(Scene) 저장 및 로드: Inspector에 입력한 값이 유지됨
✅ ScriptableObject: 게임 데이터 관리
✅ Save/Load 시스템: JSON 또는 Binary 직렬화를 활용하여 파일 저장
2️⃣ Unity에서 직렬화 가능한 타입
https://docs.unity3d.com/6000.0/Documentation/Manual/script-serialization-rules.html
Unity는 특정 데이터 타입만 직렬화할 수 있도록 제한하고 있습니다.
⭕ 직렬화 가능한 타입 (Serializable)
✅ 기본 데이터 타입: int, float, bool, string 등
✅ Unity 기본 타입: 배열 & 리스트: int[], List<float> 등 (단, public 또는 [SerializeField] 필요)
✅ 사용자 정의 클래스 ([System.Serializable] 필요)
✅ ScriptableObject
❌ 직렬화 불가능한 타입 (Non-Serializable)
❌ 딕셔너리(Dictionary)
❌ 다차원 배열 (int[,])
❌ 속성(Property) (getter/setter)
❌ Static 변수 (static)
❌ 추상 클래스 & 인터페이스
❌ 델리게이트(Delegate), 이벤트(Event)
3️⃣ Unity 직렬화 적용 방법
✔️ [SerializeField]
private 변수도 Inspector에서 보이도록 만들고, 직렬화 가능하게 합니다.
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField] private int health = 100; // 직렬화됨 (Inspector에서 수정 가능)
private int score = 0; // 직렬화되지 않음 (Inspector에서 보이지 않음)
}
✅ [SerializeField]를 사용하면 private 변수도 직렬화됨
❌ 하지만 static, const, readonly 변수는 직렬화되지 않음
✔️ [System.Serializable]
사용자 정의 클래스를 직렬화하려면 [System.Serializable]을 붙여야 합니다.
using UnityEngine;
[System.Serializable]
public class Weapon
{
public string name;
public int damage;
}
public class Player : MonoBehaviour
{
public Weapon myWeapon; // Weapon 클래스가 직렬화되므로 Inspector에서 수정 가능
}
✅ 클래스를 System.Serializable로 만들면 Unity Inspector에서 확인 가능
❌ 하지만 Dictionary, Properties, Static 변수 등은 여전히 직렬화되지 않음
✔️ ScriptableObject
게임 데이터를 저장 및 관리하는 특수한 직렬화 객체
using UnityEngine;
[CreateAssetMenu(fileName = "New Weapon", menuName = "Weapon")]
public class WeaponData : ScriptableObject
{
public string weaponName;
public int damage;
}
✅ 씬(Scene)과 독립적으로 데이터 관리 가능
✅ 메모리 효율적 관리 가능 (오브젝트 풀링, 설정 저장 등)
❌ 런타임에서 수정된 값은 저장되지 않음 (Play 모드가 끝나면 초기화됨)
4️⃣ Unity 직렬화와 JSON 활용
Unity에서 JSON 직렬화를 활용하면 데이터 저장 & 로드가 가능해집니다.
✔️ JsonUtility (빠르지만 제한적)
using UnityEngine;
[System.Serializable]
public class PlayerData
{
public string name;
public int level;
}
public class SaveLoadSystem : MonoBehaviour
{
void Start()
{
PlayerData player = new PlayerData { name = "John", level = 10 };
string json = JsonUtility.ToJson(player);
Debug.Log(json); // {"name":"John","level":10}
PlayerData loadedPlayer = JsonUtility.FromJson<PlayerData>(json);
Debug.Log(loadedPlayer.name); // John
}
}
✅ 빠름 & Unity 기본 지원
❌ Dictionary, List<T> 같은 복잡한 자료형 지원 X
✔️ Newtonsoft.Json (더 강력한 JSON 직렬화)
Newtonsoft.Json 라이브러리를 사용하면 Dictionary, List, Interface 등도 직렬화 가능
using UnityEngine;
using Newtonsoft.Json;
using System.Collections.Generic;
public class PlayerData
{
public string name;
public int level;
public Dictionary<string, int> inventory = new Dictionary<string, int>();
}
public class SaveLoadSystem : MonoBehaviour
{
void Start()
{
PlayerData player = new PlayerData { name = "John", level = 10 };
player.inventory.Add("Sword", 1);
player.inventory.Add("Potion", 5);
string json = JsonConvert.SerializeObject(player, Formatting.Indented);
Debug.Log(json);
PlayerData loadedPlayer = JsonConvert.DeserializeObject<PlayerData>(json);
Debug.Log(loadedPlayer.inventory["Sword"]); // 1
}
}
✅ Dictionary, List<T> 등 복잡한 자료형 지원
❌ JsonUtility보다 속도가 느림
❌ 추가 라이브러리 설치 필요 (Newtonsoft.Json.dll)


