바야바네 움집
[JSON/Newtonsoft] JsonConvert.DeserializeObject<T>(string json) error 본문
[JSON/Newtonsoft] JsonConvert.DeserializeObject<T>(string json) error
친절한 바야바 2022. 4. 1. 07:31Deserialize 하면서 발생한 에러 2개
1. Object Reference not set to an instance of an object
2. Debug.log(questData); // NULL
+) Rescources.Load를 쓰면 좋지 않다고 그래서 베르님 블로그에서 FileStream을 사용하는 코드를 가져다가 썼다. JsonConvert.DeserializeObject<T>는 마지막 줄에 있다.
public T LoadJsonFile<T>(string loadPath, string fileName)
{
FileStream fileStream = new FileStream(string.Format("{0}/{1}.json", loadPath, fileName), FileMode.Open);
byte[] data = new byte[fileStream.Length];
fileStream.Read(data, 0, data.Length);
fileStream.Close();
string jsonData = Encoding.UTF8.GetString(data);
return JsonConvert.DeserializeObject<T>(jsonData);
}
1. Object Reference not set to an instance of an object
- 콘솔
- 틀린 코드
public class QuestUI : MonoBehaviour
{
QuestData questData;
DataManager dataManager;
void Start()
{
questData = new QuestData();
questData = dataManager.LoadJsonFile<QuestData>(Application.dataPath + "/MAIN/Data", "quest");
}
}
- 왜 틀렸을까?
DataManager를 아직 싱글톤으로 만들기 전이라서 단순히 선언하는 것만으로는 값을 얻어오지 못했음. 따라서 questData 변수에 QuestData 객체를 새로 생성해준 것처럼 dataManager 변수에도 DataManager 객체를 생성해서 붙여줘야 함.
- 수정한 코드
void Start()
{
questData = new QuestData();
dataManager = new DataManager();
questData = dataManager.LoadJsonFile<QuestData>(Application.dataPath + "/MAIN/Data", "quest");
}
이렇게 만들어서 붙여주면 에러 사라짐
2. Debug.log(questData); // NULL
- 콘솔
- 틀린 코드
public class QuestUI : MonoBehaviour
{
QuestData questData;
DataManager dataManager;
void Start()
{
questData = new QuestData();
dataManager = new DataManager();
questData = dataManager.LoadJsonFile<QuestData>(Application.dataPath + "/MAIN/Data", "quest");
Debug.Log(questData);
Debug.Log(questData.title);
}
}
- 왜 틀렸을까?
여기서 내가 작성한 JSON 파일을 살펴보면 이렇다.
{
"000_quest": {
"title": "시작",
"content": "상하좌우로 움직이기",
"goal": [
{
"type": "bool",
"content": "상"
},
{
"type": "bool",
"content": "하"
},
{
"type": "bool",
"content": "좌"
},
{
"type": "bool",
"content": "우"
}
],
"reward": {
"exp": 1000,
"money": 1000
}
}
}
그리고 QuestData 코드를 살펴보면 이렇다.
public class QuestData
{
public string title;
public string content;
public List<Goal> goal;
public Reward reward;
}
public class Goal
{
public readonly string type;
public readonly string content;
}
public class Reward
{
public readonly float exp;
public readonly float money;
}
^^
아주 바보같은 실수.
JSON의 맨 첫번째 줄을 보면 여러 개의 Quest 들을 분리하기 위해 ###_Quest 형식으로 오브젝트를 선언했다. 그러니 QuestData 클래스에 해당하는 변수들은 이 ###_Quest 오브젝트 안에 포함되어 있는 것임...
따라서 Dictionary<string, QuestData> 변수를 만들어 Deserialize 된 데이터를 담아줘야 한다. 그럼 string에 ###_Queset 가 저장되고 QuestData 에는 지금껏 내가 저장하고자 의도했던 데이터가 저장된다.
우하하
- 수정한 코드
public class QuestUI : MonoBehaviour
{
QuestData questData;
DataManager dataManager;
Dictionary<string, QuestData> questDict;
void Start()
{
questData = new QuestData();
dataManager = new DataManager();
questDict = dataManager.LoadJsonFile<Dictionary<string, QuestData>>(Application.dataPath + "/MAIN/Data", "quest");
}
}
짜잉남
'🎮유니티Unity' 카테고리의 다른 글
사용자 지정 숫자 서식 (0) | 2022.03.26 |
---|