본문 바로가기

Unity/유니티 이론

직렬화 (Srialize)

직렬화 단어를 이해하려면 USB(Universal *Serial Bus) 인터페이스를 보면 됩니다.

*Serial - 연쇄, 연속해서 이어지는 어떤 것.

 

컴퓨터 -------- USB 메모리

- 연속된 드라마 (Serial Drama), 연속적인 데이터(011011001)를 표현할 때도 사용합니다.

- 범용적으로 직선상으로 연속해서 들어오는 데이터를 받아 들이 수 있는 인터페이스

 

직렬화 (Serialization)

- 오브젝트를 연속된 문장형 데이터나 연속된 Byte 데이터로 바꾸는 것입니다.

object ---> string or bytes

메모리 ---> 드라이브 or 통신선

- 이런 작업을 하는 이유?

    ㄴ object는 메모리에 존재하고 string과 bytes data는 drive에 저장도 할 수 있고,

         통신 선을 통해서 전송할 수 있기 때문입니다.

 

역직렬화 (DeSerialization)

- 이미 존재하는 string data나 bytes data 또는 byte file로 부터 object를 생성하는 행위입니다.

object <--- string or bytes

메모리 <--- 드라이브 or 통신선

 

Unity에서는 게임 엔진 에디터

- 유니티에서 스크립트(Script)의 변수를 Public으로 지정하여 Inspector에서 값을 변경하는 경우가 있습니다. 그러나 정보를 은닉하고 캡슐화를 유지하기 위해 private로 변수를 지정한 경우에는Inspector에서 볼 수가 없습니다. 이때 Inspector에서 볼 수 있도록 하는 것이 "SerializeField"입니다. SerializeField는 직렬화를 하겠다는 뜻입니다.

- 참고로 유니티 에디터의 Inspector에는 사용자가 정의한 클래스(Class) 또는 구조체(Structure)의 정보가 Inspector에 노출되지 않는데, System에서 제공하는 "Serializable" 키워드를 지정해서 직렬화 할 수 있습니다.

 

- 게임 엔진 에디터에서 게임 오브젝트 A를 편집한다고 했을 때 편집한 A object의 정보가 게임 에디터를 정리하고 나중에 다시 실행 했을 때 유지 되어 있는 것은 이상합니다.

- 왜냐하면 object는 프로그램에게 할당 된 메모리에 존재하고, 프로그램이 종료되면 해당 프로그램이 사용 중이던 메모리에 모든 오브젝트도 같이 파괴되기 때문입니다.

- 하지만, 실제로는 게임 엔진 에디터를 끄고 다시 켰을 때 수정 사항이 그대로 존재합니다.

    ㄴ 그 이유로는, object에게 serialization화 가능하다는 표시가 붙어 있기 때문입니다.

- 즉, 우리는 GameObject에 편집했다고 생각했지만 실제로는 Serialization을 통해서 편집된 GameObject의 정보가 텍스트 파일로서 우리들의 컴퓨터 어딘가에 저장 되어 있던 것입니다.

- 그렇게 파일로서 저장된 GameObject A의 정보가 있기 때문에 나중에 게임 엔진 에디터를 다시 실행했을 때 해당텍스트 파일로부터 역직렬화(DeSerialization)를 통해서 GameObject A를 생성하는 것입니다.

 

게임 엔진 에디터                                  텍스트

       A Object               --->               메모리 어딘가

                            Serialization

 

게임 엔진 에디터                                  텍스트

       A Object              <---               메모리 어딘가

                          DeSerialization

 

1번 컴퓨터 -------------------------------------------------------------------------> 2번 컴퓨터


    A     -------------------> "0101001"----------------->  "0101001" ----------------> A 
             Serialization                                                          DeSerialization

 

1번 컴퓨터에 object A가 존재하는데 이 object를 2번 컴퓨터에 전송하고 싶다고 봤을 때 문제는 사용하는 하드웨어, 운영 체제, 프로그래밍 언어가 다 다릅니다. 그리고, object A는 물리적인 회선으로 전송 가능한 type이 아니라 메모리에 존재하는 추상적인 type입니다. 하지만, 두 컴퓨터 모두 공통적인 사항이 있습니다. 두 컴퓨터모드 "0101"이라는 이진법 신호를 byte data를 다룰 수 있습니다. byte data는 물리적인 회선을 통해서 전기 신호로 전송할 수 있습니다. 즉, 두 컴퓨터가 회선으로 연결되었다고 봤을 때 먼저, 첫 번째 컴퓨터에서 object를 물리적인 회선을 통해서 전송할 수 있는 byte data로 직렬화합니다. 그리고, 그 byte data를 회선을 통해서 2번 컴퓨터로 전달합니다. 그렇게 전송 받은 byte data를 2번 컴퓨터에서는 역직렬화 해야합니다. 왜냐하면, 다운로드 받은 byte data는 그저 파일일뿐이니까 파일은 메모리에 존재하는 실체가 아닙니다. 메모리에 존재하는 실체로 만들기 위해서는 byte data를 역직렬화를 통해서 실제로 존재하는 object로 탄생시킵니다.

 

비슷한 예)

Web ------------ Json ------------> Sever

서버와 웹 브라우저 사이에서 데이터를 주고 받았을 때 json format을 사용해서 object를 주고 받습니다.

object에서 json file로 직렬화 해서 전송을 하고, 다운 받은 json file에서 역직렬화 해서 object를 복구합니다.

그래서 object를 직렬화/역직렬화 하는데 사용되는 format은 굉장히 많습니다. 하지만 핵심은 같다고 볼 수 있습니다!

추상적인 object를 구체적이고 저장 가능하고 전송 가능한 단순한 text file 또는 연속된 byte 정보 등으로 바꿔 주는 것입니다.

object < ------- > 단순 text file (Bytes, XML, Json, YAML..)

 

Server <--- Data ---> Client

Json - 웹이나 네트워크에서 서버와 클라이언트 사이에 데이터를 주고 받을 때 사용하는 개방형 표준 포맷

- 좀 더 쉽게 말하면 어떻게 서버와 클라이언트 사이에 데이터를 주고 받을 지에 대한 약속 같은 것.

- Json이라는 포맷은 텍스트를 사용하기 때문에 사람이 이해하기 쉽다는 장점을 가지고 있습니다.

- 그래서 유니티에서도 상당히 많이 사용 되며, 네트워크 게임을 개발할 때 게임에 필요한 데이터를 주고 받고나, 게임 진행 상황이나 게임 설정을 저장하는 식으로 사용합니다.

- XML이라는 것도 사용 범위가 거의 일치하지만, Json에 비해서 가독성이 떨어지고 데이터를 넣거나 꺼내기 위해서 파싱하는 과정이 까다로운 반해서, Json은 XML에 비해서 가독성이 좋고 직렬화 비직렬화 함수를 통해서 오브젝트에서 Json 데이터로, Json 데이터에서 오브젝트로 편하게 반환할 수 있다는 장점이 있습니다.

 

Json 데이터는 텍스트로 구성됩니다.

{
    "Name": "Test",
    "WalkSpeed": 3.0,
    "RunSpeed": 6.0,
    "CurrentHp": 300.0,
    "MaxHp": 300.0,
    "CurrentMp": 400.0,
    "MaxMp": 400.0,
    "CurrentStamina": 10.0,
    "AttackDamage": 5.5,
    "CriticalDamage": 8.25,
    "CriticalChance": 13.0,
    "Defense": 0.0,
    "CurrentExp": 7.0,
    "RequiredExp": 174.0,
    "Level": 2,
    "Money": 0,
    "CurrentScene": "Village"
}

 

ex) 캐릭터 스탯 테스트

이런 형태의 구조를 가지고 있습니다.

 

Json의 데이터는Key와 Value의 쌍으로 이루어진 데이터로 저장하는데, Items와 같이 배열로 된 데이터 역시 저장이 가능하고, 객체 안에 객체를 넣는 것도 가능합니다. 그리고 데이터 내용이 문자열로 되어 있기 때문에 사람이 알아 보기 매우 쉽습니다. Json 데이터에서 중괄호는 객체를 의미하고, 대괄호는 순서가 있는 배열을 나타냅니다.

그리고, Json은 정수, 실수, 문자열, boolean, null 등의 데이터 타입을 지원합니다.

추가로 Json은 주석을 지원하지 않기 때문에, Json 파일을 사람이 읽고 수정할 수 있도록 할 계획이라면 Key 값의 이름을 명확하게 정해서 이 값이 무엇을 의미하는지 알려주는게 좋다. 이런, Json의 단점으로는 작은 문법 오류에도 민감하게 반응한다는 점.

중간에 중괄호나 대괄호, 콜론, 쉼표 하나라도 빠지면 Json 파일이 깨져버리고 문자열 형태인 Json 데이터를 원하는 데이터로 변환할 수 없게 됩니다. 이런 문제 때문에 Json 검사기를 찾아보면 Json 데이터가 유효한지 검사해주는 웹 페이지들이 많습니다.

Json 데이터를 작성하고 난 뒤에는, Json 데이터 파일의 깨짐으로 인한 버그를 막기 위해서 Json 검사기로 검사하고 사용하는 것이 좋습니다.

 

참고

https://www.youtube.com/watch?v=qrQZOPZmt0w

 

'Unity > 유니티 이론' 카테고리의 다른 글

유니티 회전  (0) 2024.07.01