JSON사용할때 JsonUtility 에서 newtonsoft로 교체

2024. 12. 27. 17:42카테고리 없음

처음에 밑에 코드와 같이 JsonUtility를 사용해서 JSON데이터를 다뤘는데 JSON에서 데이터를 가져올때 List형식으로 바꿔주야하는데 JsonUtility에서는 바꿔주기가 힘든거 같아서 JSON을 더 다양하게 사용할 수 있는 newtonsoft를 사용하기로 결정했다.

public void SaveData<T>(T data)
{
    string json = JsonUtility.ToJson(data, true);
    File.WriteAllText(Application.persistentDataPath + $"/{typeof(T)}.txt", json);
}

public T LoadData<T>()
{ 
    string filePath = Application.persistentDataPath + $"/{typeof(T)}.txt";
    if (!File.Exists(filePath))
    {
        return default;
    }
    
    string loadJson = File.ReadAllText(Application.persistentDataPath + $"/{typeof(T)}.txt");
    return JsonUtility.FromJson<T>(loadJson);
}

 

하지만 나는 List로 반환해야하니깐

public void SaveData<T>(T data)
{
    string json = JsonUtility.ToJson(data, true);
    File.WriteAllText(Application.persistentDataPath + $"/{typeof(T)}.txt", json);
}

public List<T> LoadDataList<T>()
   {
       string filePath = Application.persistentDataPath + $"/{typeof(T)}.txt";
       Debug.Log(filePath);
       if (!File.Exists(filePath))
       {
           return new List<T>();
       }
       
       string loadJson = File.ReadAllText(Application.persistentDataPath + $"/{typeof(T)}.txt");
       return JsonConvert.DeserializeObject<List<T>>(loadJson);
   }

 

문제 (같은 경로로 파일을 저장 불러오기가 안되고있음)

이런식으로 변환해준다음에 코드를 작성하니깐 데이터는 잘 전달이 되는데 불러와 지는게 안된다. 그래서 디버그를 중간중간에 추가해서 실행을 해보니

public void SaveData<T>(T data)
{
    string json = JsonConvert.SerializeObject(data, Formatting.Indented);
    string filePath = Application.persistentDataPath + $"/{typeof(T).Name}.txt";
    Debug.Log(typeof(T).Name);
    File.WriteAllText(filePath, json);
}

public List<T> LoadDataList<T>()
{
    string filePath = Application.persistentDataPath + $"/{typeof(T).Name}.txt";
    Debug.Log($"파일 경로 : {filePath}");
    if (!File.Exists(filePath))
    {
        return new List<T>();
    }
    
    string loadJson = File.ReadAllText(filePath);
    return JsonConvert.DeserializeObject<List<T>>(loadJson);
}

LoadDataList<T>에서 실행되는 디버그로그는 밑에 사진과 같이 경로가 찍히는데

SaveData<T>에서 실행되는 디버그로그는 

이렇게 찍혔다. 저장하는 곳은 List 타입으로 저장이 되는데 불러오는거는 ItemInstance로 불러오니깐 데이터가 안불러와지는거다.

그래서 왜이렇게 되냐 찾아봤더니.....

데이터를 저장할때 밑에 코드와 같이 저장을 하는데 이때 

public ItemInstance AddItem(int itemId, int itemCount)     //아이템 추가하는 로직
{
    var item = new ItemInstance();
    {
        item.id = nextId;
        item.itemId = itemId;
        item.count = itemCount;
        item.enhance = 0;
        item.equip = false;
        item.gradeType = GetGradeType(itemId);
    }

    _items.Add(item);
    
    DatabaseManager.Instance.SaveData(_items);
    AddId();
    return item;
}

이때 추가하는 _items의 타입이 List타입이여서 제네릭에서 받을때 List로 저장이 된 것이다.

[SerializeField]private List<ItemInstance> _items;

불러올때에는 해당 제네릭 타입을 ItemInstance로 정해줬기때문에 ItemInstance로 되는 것이다.

ItemManager.Instance.Initialize(DatabaseManager.Instance.LoadDataList<ItemInstance>());

문제 해결

그래서 데이터를 저장하는 부분에서 string 으로 fileName을 받아와서 넣어주고

public void SaveData<T>(T data, string fileName)
{
    string json = JsonConvert.SerializeObject(data, Formatting.Indented);
    string filePath = Path.Combine(Application.persistentDataPath, $"{fileName}.txt");
    Debug.Log(typeof(T).Name);
    File.WriteAllText(filePath, json);
}

저장하는 함수를 호출하는 곳에서는 item의 타입을 string으로 변환시켜줘서 주면 해결이 된다.

public ItemInstance AddItem(int itemId, int itemCount)     //아이템 추가하는 로직
{
    var item = new ItemInstance();
    {
        item.id = nextId;
        item.itemId = itemId;
        item.count = itemCount;
        item.enhance = 0;
        item.equip = false;
        item.gradeType = GetGradeType(itemId);
    }

    _items.Add(item);
    DatabaseManager.Instance.SaveData(_items, item.GetType().ToString());
    AddId();
    return item;
}