
직렬화(Serialization)는 데이터 구조나 오브젝트 상태를 저장하거나 전송할 수 있는 형식으로 변환하는 과정을 말한다. 이 변환된 형식은 파일에 저장하거나 네트워크를 통해 전송할 수 있다. 직렬화의 주요 목적은 데이터 구조를 쉽게 공유하고 사용할 수 있도록 하는 것이다.
역직렬화(Deserialization)는 직렬화의 반대 과정으로, 직렬화된 데이터를 원래의 데이터 구조나 오브젝트 상태로 복원하는 것을 말한다.
직렬화와 역직렬화는 데이터를 저장하고 전송하는 데 매우 중요한 역할을 한다. 이를 통해 다양한 시스템과 언어 간에 데이터를 쉽게 공유할 수 있다.
어딘가에 정보를 올려놨다가 (직렬화)
그걸 다시 그대로 가져올 수 있다 (역직렬화)
유니티에서 실습하며 많이 사용했던 PlayerPrefs도 직렬화하는 방식이다.
String형식으로 저장하고 Split을 통해 역직렬화 할 수 있지만 보안에 취약하다.
직렬화
- Player Data
1. Nickname
2. Lv
3. Hp
⇒ string PlayerData = Nickname + ‘,’ + Lv + ‘,’ + Hp
- PositionData
1. Vector3을 x,y,z값으로 변환하여 문자열로 만들고 저장
역질렬화
- String.Split(',') 이용
엑셀을 통해 자료를 불러오기 때문에 아이템 데이터 베이스를 이용한다거나 기획자랑 협업할 때 편리하게 이용할 수 있다.
PlayerPrefs와 같이 Split을 이용하되, 행간 구분을 위해 '\n'을 이용해 두 번 역직렬화를 해야한다.
역직렬화
TextAsset csvData = Resources.Load<TextAsset>(”CSVData”);
TrimEnd()를 통해 끝쪽 빈 공백을 날릴 수 있음.
정보의 구조를 쉽게 알아볼 수 있지만 작성이 까다롭다. 정해진 포맷이 정확하게 일치해야함
using System.Xml;
using UnityEngine;
public class XMLTest : MonoBehaviour
{
Player player;
void CreateXML()
{
XmlDocument xmlDoc = new XmlDocument();
// 헤더 (없어도 됨)
xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "yes"));
//---------- 구조 ----------//
// 루트 노드
XmlNode root = xmlDoc.CreateNode(XmlNodeType.Element, "GameData", string.Empty);
xmlDoc.AppendChild(root);
// 자식 노드
XmlNode child = xmlDoc.CreateNode(XmlNodeType.Element, "PlayerData", string.Empty);
xmlDoc.AppendChild(child);
//--------------------------//
//---------- 내용 -----------//
XmlElement nickname = xmlDoc.CreateElement("nickname");
nickname.InnerText = player.name;
child.AppendChild(nickname);
// 데이터 추가 가능
//--------------------------//
// 저장
xmlDoc.Save("./Assets/Resources/GameDatas.xml");
// 불러오기
void LoadXML()
{
// 저장됐던 데이터를 그대로 가져온다.
var t = Resources.Load<TextAsset>("GameDatas");
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(t.text);
// 미리 구조화된 Xml에서 원하는 부분을 정해 가져올 수 있다.
XmlNodeList nodes = xmlDoc.SelectNodes("GameData/PlayerData");
XmlNode playerData = nodes[0];
player.name = playerData.SelectSingleNode("nickName").InnerText;
}
}
}
가장 편리하고 가장 많이 쓰인다. 여러가지 방법이 있는데 대표적 방법 3가지
Newonsoft
LitJson
JsonUtility
유니티에서는 JsonUtility가 특화되어 있기 때문에 정말 특별한 경우가 아니라면 현업에서도 JsonUtility를 사용한다고 한다.
using System.Collections.Generic;
using UnityEngine;
public class Character : MonoBehaviour
{
public UserData data;
private void Start()
{
// 직렬화 끝
var t = JsonUtility.ToJson(data);
}
}
// 유니티 에디터에서 직렬화하기위해서
[System.Serializable]
public class UserData
{
public string nickName;
public int lv;
public float hp;
// Serializable된 데이터들을 확장하기 용이하다.
public List<string> friends = new List<string>();
public List<Inventory> inventories = new List<Inventory>();
// 추가 정보들
}
[System.Serializable]
public class Inventory
{
public int size;
public List<int> itemIds = new List<int>();
}

저장과 불러오기가 굉장히 간단하다.
JSON은 특히나 서버와의 통신을 위해 많이 쓰이게 된다고 한다.
서버 통신 없이 로컬에 저장되는 JSON은 쉽게 접근이 가능하므로, 플레이어의 정보등을 담아둬선 안되며, 서버를 쓸 수 없는 상황이라면 꼭 암호화를 거쳐서 저장하는것이 좋다.
SO는 JSON으로 직렬화가 불가능한 유니티의 거의 모든 것들을 직렬화 할 수 있다.
다만, SO로 저장된 데이터는 프로그램에선 데이터가 변동되어도 잘 작동하지만 Build했을 때는 데이터가
처음에 셋팅한 값으로 고정되어 프로그램을 껐다 키면 원래대로 돌아간다고 한다.
따라서 몬스터의 초기값등 고정된 값에만 쓰고, 플레이어의 상태등 변동하는 데이터는 SO를 이용해선 안된다.