바야바네 움집

[JSON/Newtonsoft] JsonConvert.DeserializeObject<T>(string json) error 본문

🎮유니티Unity

[JSON/Newtonsoft] JsonConvert.DeserializeObject<T>(string json) error

친절한 바야바 2022. 4. 1. 07:31

Deserialize 하면서 발생한 에러 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
Comments