목차
먼저 프로젝트 기한이 두 달 남은 상태에서 공부용으로 조사한거라 코드를 거의 들고와 죄송죄송;;;
프로젝트 구현하면서 천천히 변경하겠음. 히히;;;
Step0-1. 직렬화, 역직렬화
- 종이로 출력된 종이 뭉치를 서버로 보내고 싶어도 데이터가 아닌 실물(객체)이기 때문에 보낼 수 없음
- 최소한 스캔 떠서 이미지로 변환시켜야 하지
- 수정 가능한 파일로 보내고 싶으면 엑셀 파일을 찾던가 서류를 보고 직접 찍어내던가
- 객체에 대한 정보를 서버 등에 저장하거나 전송하기에 적합하도록 변환하는게 직렬화.
- 그걸 다시 객체로 푸는게 역직렬화
System.Text.Json 네임스페이스는 JSON(JavaScript Object Notation)에서 직렬화 및 역직렬화하는 기능을 제공
Serialization : 개체의 상태(:속성 값)를 저장매체에 저장하거나 바이너리 형태로 네트워크를 통해 전달할 수 있는 형식으로 변환하는 프로세스
Deserializtion : 직렬화된 형식에서 개체를 다시 생성.
Stream이란
일련의 데이터가 한 곳에서 다른 곳으로 직렬로 이동하는 상태(흐름)
: 걍 프로그램과 주변 장치가 통신하는 수단이라는 뜻
직렬화의 장단점
장점
- DOM을 이용하지 않고 XML 수정
- 다른 어플리케이션으로부터 객체를 전달할 수 있다.
- 다른 도메인으로 객체를 전달할 수 있다.
- 방화벽에 제약을 받지 않고 객체를 XML 문자열 형태로 전달 할 수 있다.
단점
- 직렬화, 역직렬화는 자원의 소모가 많다?
- 네트워크를 통해 전달할 경우 지연 문제가 발생할 수 있다.
- 안전하지 않고(제 3자가 수정 가능하므로), 많은 저장 공간을 차지하며, public 클래스에 대해서만 직렬화가 이뤄질 수 있으므로 private이나 internal 클래스는 직렬화 할 수 없다.
Step1. Json이란
- 웹, 네트워크 기준, 서버와 클라이언트 사이 데이터 송수신용 개방형 표준 포맷.
- 어떻게 서버와 클라이언트 사이 데이터를 주고 받는지
- Json 포맷은 텍스트로 되어있어 사람이 이해하기 쉽다.
- 데이터 타입 : 정수, 실수, 문자열, 불리언, null 등
- 중괄호 : 객체, 대괄호 : 배열
- 언제 씀?
- 저장, 통신 등
- 어캐 씀?
- 유니티 지원 기능
- 단, 미스나면 바로 깨져서 검사기 한번 거치고 사용하자.
class Data
{
public string name,
public int level,
public int coin = 100,
public bool skill
}
public class Test : MonoBehaviour
{
Data player = new Data() { name = "chad", level = 50, coin = 200, skill = false }
void Start()
{
string jsonData = JsonUtility.ToJson(player);
Data player2 = JsonUtility.FromJson<Data>(jsonData);
print(player2.name);
print(player2.level);
print(player2.coin);
print(player2.skill);
}
}
Step2. Json 파싱
파싱(Parsing) : 구문분석, 문장을 이루는 구성 성분을 분해하고 위계 관계를 분석해 구조를 결정하는 것. 즉 데이터를 조합해 원하는 데이터를 빼내는 것
단일 객체 불러오기
Serializable 클래스 생성
json 객체를 불러오려면 객체를 래핑할 클래스를 만들어야 한다.
가령 객체에서 hp, atk, def 등에 대한 정보를 꺼내오려면 아래와 같은 클래스나 객체가 필요함.
[System.Serializable]
class Stat
{
public int hp, atk, def;
}
Json 파일 읽기
var loadedJson = Resources.Load<TextAsset>("Json/Stats");
stat my Stat = JsonUtility.FromJson<Stats>(loadedJson.ToString());
다중 객체 불러오기[여기부터 보완]
{
"EquipableItems": [
{
"part":"Head",
"damage":"0",
"defance":"10",
}
{
"part":"Glove",
"damage":"0",
"defance":"7",
}
]
}
위 경우 JsonUtility는 한 클래스로 가져오지 못함.
따라서 json 파일에서 객체로 보이는 건 전부 다 클래스로 감싸줘야함.
[System.Serializable]
class EquipInfo : IComparable
{
public string part;
public int hp, atk, def;
}
[System.Serlizable]
class EquipData
{
public EquipInfo[] EquipableItems;
}
[System.Serlizable]
class EquipData
{
public List<EquipInfo> EquipableItems;
}
- 배열을 담으려면 EquipInfo의 배열로 이뤄진 새로운 클래스나 배열을 정의
단, Json의 프로퍼티 이름과 배열/리스트의 이름이 같아야 함을 주의하도록.
여기까지 파싱
void Start()
{
TextAsset textAsset = Resources.Load<TextAsset>("~/EquipableItems");
EquipData EquipableItems = JsonUtility.FromJson<EquipableItems>(textAsset.text);
}
다시 Json으로 변환하려면
string classToJson = JsonUtility.ToJson(lottoList);
다중 객체 내부의 배열 프로퍼티
{
"skills": [
{
"type": "attack",
"method":
[
{
"name": "rangedAttack",
"attackDmg": 45,
"heal" : 0
"target": [ 1 ]
},
{
"name": "distanceAttack",
"attackDmg": 25,
"heal" : 0
"target": [ 1, 2, 3 ]
}
]
"type": "heal",
"method":
[
{
"name": "singleheal",
"attackDmg": 0,
"heal" : 50
"target": [ 1 ]
},
{
"name": "multiheal",
"attackDmg": 0,
"heal" : 25
"target": [ 1, 2, 3 ]
}
]
]
}
}
//대충 작성 나중에 고치자
//아마 구조적으로 잘못 쓴 것 같은데 급해서 쩔수 없음.
- 새로운 클래스 정의
[Serializable]
public class SkillCase //aray of objects
{
public string name;
public int damage;
public int heal;
public int[] target;
}
- 파싱
public class ParsingJson : MonoBehaviour
{
[Serializable]
public class PlayerSkill
{
public SkillCase[] playerskill;
}
[Serializable]
public class SkillNumbers
{
public PlayerSkill[] skills;
}
void Start()
{
TextAsset textAsset = Resources.Load<TextAsset>("~/skills");
SkillNumbers skillList = JsonUtility.FromJson<SkillNumbers>(textAsset.text);
foreach ( PlayerSkill skill in skillList.skills )
{
//대충 출력 함수 코드
}
//비직렬화 후 디버그
string classToJson = JsonUtility.ToJson(skillList);
Debug.Log(classToJson);
}
}
끝
Json 출력
- Json 쓰기
string fileName = "test.json";
string path = Application.dataPath + "/" + fileName;
File.WriteAllText(path, classToJson);
- prettyPrint 옵션 == json 파일 정렬 저장(?) 기능
string classToJson = JsonUtility.ToJson(lottoList, true /* prettyPrint */);
끝
Json 파일 읽기
나중에 채워 넣기
Json 파일 쓰기
JObject configData = new Object
{
new JProperty("IP", "");
new JProperty("IP", "");
new JProperty("IP", "");
new JProperty("IP", "");
new JProperty("IP", "");
{
configData.Add("USERS", JArray.FromObject(userList));
FIle.WriteAllText(Path, configData.ToString());
궁금한점
- 클래스 상속 받는 것 처럼
- item - equip
- item- stackable
- 등으로 작성하고 정규화를 이용해 탐색하고 싶은데
어캐 작성함?- 걍 같은 원소를 가지도록 작성하고 원할 때 파싱하면 될 듯? 아마도?
- 해보고 안되면 물어봐야징
- 걍 같은 원소를 가지도록 작성하고 원할 때 파싱하면 될 듯? 아마도?
Step3. JsonUtility와 Json.NET 혹은 Newtonsoft.Json
아래 내용은 아직 변형할 능력도 없고 프로젝트 중이라 시간이 없어서
자료 모으는 느낌으로 다른 블로그에서 긁어온 것.
차후 프로젝트에서 사용한 코드로 대체하겠음
NewtonSoft.Json
나중에 작성
지금은 뉴톤으로 안쓸거라
나중에 필요하면 조사하고 작성할 듯
- 멤버 함수라도 적으려 했는데 왜 안 보이지?
JsonUtility 예시 11
Json데이터 클래스 생성
[Serializable]
public class JsonData
{
public string name;
public int age;
public float height;
public bool man;
public string description;
public string[] tools;
}
클래스 인스턴스 생성 후 값 할당
JsonData jsonData = new JsonData();
jsonData = new JsonData();
jsonData.name = "coderzero";
jsonData.age = 48;
jsonData.height = 172.5f;
jsonData.man = true;
jsonData.description = null;
jsonData.tools = new string[3];
jsonData.tools[0] = "Unity";
jsonData.tools[1] = "Visual Studio";
jsonData.tools[2] = "Phtoshop";
인스턴스를 Json 포맷으로 직렬화
string toJson = JsonUtility.ToJson(jsonData);
{"name":"coderzero","age":48,"height":172.5,"man":true,"description":"","tools":["Unity","Visual Studio","Phtoshop"]}
Json 포맷에서 클래스나 구조체로 역직렬화
JsonData fromJson = JsonUtility.FromJson<JsonData>(toJson);
파일 저장
File.WriteAllText(@"D:\JsonExample.json", toJson);
파일 읽기
string readJson = File.ReadAllText(@"D:\JsonExample.json");
예제
using UnityEngine; using System; // 2.1 네임스페이스 Serializable using System.IO; // 2.1 네임스페이스 File // 2.2 Json 데이터 클래스 생성 [Serializable] public class JsonData { public string name; public int age; public float height; public bool man; public string description; public string[] tools; } public class JsonExample : MonoBehaviour { void Start() { // 2.3 클래스 인스턴스 생성 후 값 할당 JsonData[] jsonData = new JsonData[2]; jsonData[0] = new JsonData(); jsonData[0].name = "coderzero"; jsonData[0].age = 48; jsonData[0].height = 172.5f; jsonData[0].man = true; jsonData[0].description = null; jsonData[0].tools = new string[3]; jsonData[0].tools[0] = "Unity"; jsonData[0].tools[1] = "Visual Studio"; jsonData[0].tools[2] = "Phtoshop"; jsonData[1] = new JsonData(); jsonData[1].name = "coderzero"; jsonData[1].age = 48; jsonData[1].height = 172.5f; jsonData[1].man = true; jsonData[1].description = null; jsonData[1].tools = new string[2]; jsonData[1].tools[0] = "3D Max"; jsonData[1].tools[1] = "Photoshop"; // 2.4 인스턴스를 Json 포맷으로 직렬화 string toJson0 = JsonUtility.ToJson(jsonData[0]); Debug.Log(toJson0); // 출력 : {"name":"coderzero","age":48,"height":172.5,"man":true,"description":"","tools":["Unity","Visual Studio","Phtoshop"]} string toJson1 = JsonUtility.ToJson(jsonData[1]); Debug.Log(toJson1); // 출력 : {"name":"coderzero","age":48,"height":172.5,"man":true,"description":"","tools":["3D Max","Photoshop"]} // 2.5 Json 포맷에서 클래스나 구조체로 역직렬화 JsonData fromJson = JsonUtility.FromJson<JsonData>(toJson0); Debug.Log(fromJson.name); // 출력 : coderzero // 2.6 파일 저장 File.WriteAllText(@"D:\JsonExample.json", toJson1); // 2.7 파일 읽기 string readJson = File.ReadAllText(@"D:\JsonExample.json"); Debug.Log(readJson); // 출력 : {"name":"coderzero","age":48,"height":172.5,"man":true,"description":"","tools":["3D Max","Photoshop"]} } }
JsonUtility 예시 22
대충 Json
암튼 위에 Json 파일임. ㅇㅇ 파싱해야함ㅇㅇ.
using System.IO;
public class ParsingJson : MonoBehaviour
{
void Start()
{
string filePath = "~~/Equipment.Json";
string json = File.ReadAllText(filePath);
}
}
TextAsset textAsset = Resources.Load<TextAsset>("Json/Lotto1");
- TextAsset을 이용해 파일을 불러온다.
using System; /* for Serializable */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParsingJson : MonoBehaviour
{
[Serializable]
public class Items
{
public int id;
public string name;
public string part;
public int atk;
public int def;
}
...
}
- Json을 Class나 Struct로 만들기
- JSON 포맷으로 변환하기 위해서는 [Serializable]선언 필요
- json 프로퍼티대로 class를 정의하고 선언
- 이때, Json파일에 존재하지 않는 프로퍼티가 존재할 경우 default 값으로 초기화되고 에러를 발생시키지 않는다.
void Start()
{
TextAsset textAsset = Resources.Load<TextAsset>("~/Equipment");
Items equipItem = JsonUtility.FromJson<Items>(textAsset.text);
}
File.WriteAllText(filePath, classToJson);
- 파일 내보내기?
ㄹ
JsonUtility 멤버함수
- JsonUtility.FromJson : Json string을 받아 새 object를 생성해서 리턴.
- object의 클래스는 [System.Serializable]을 지원해줘야하고 public이어야 한다.
- 일반 class와 struct만 지원 (MonoBehaviour, ScriptableObject 지원ㄴㄴ)
- JsonUtility.FromJsonOverwrite : Json String과 기존 object 받아, 기존 obejct에 Json 데이터 덮어씌워줌.
- object의 클래스는 [System.Serializable]을 지원해줘야하고 public이어야 한다.
- 일반 class와 struct만 지원 (MonoBehaviour, ScriptableObject 지원ㅇㅇ)
- JsonUtility.ToJson : object 받아서, object 정보를 Json string으로 생성해서 리턴
자주 사용하는 함수와 키워드들(추가 조사 필요)
- File.ReadAllText : 텍스트 파일을 열고, 파일의 모든 텍스트를 문자열로 읽어 들인 뒤 닫는다.
- File.ReadAllText(string path) : 위와 동일
- File.ReadAllText(string path, System.Text.Encoding encoding) : 지정된 인코딩으로 읽음. 이하 위와 동일
- File.WriteAllText : 새 파일을 만들고 지정된 파일에 내용을 쓰고 파일을 닫음. 파일이 이미 있으면 덮어씀.
- File.WriteAllText(string path, string contents) : 새 파일을 만들고 지정된 파일에 내용을 쓰고 파일을 닫음. 파일이 이미 있으면 덮어씀.
- File.WriteAllText(string path, string contents, System.Text.Encoding encoding) : 지정된 인코딩으로 작성. 이하 위와 같음.
- 인코딩 : 정보의 형태나 형식을 변환하는 처리나 처리방식
- 포맷 방식 즈음으로 이해해도 되려나?
- TextAsset
Reference
Uploaded by N2T