유니티 5.3버전부터 JSON 포맷의 데이터를 파싱할 수 있는 API가 추가되었다. 플러그인을 추가하지않고, 내장된 API로만 구현을 하는 게 좋겠다싶어 조금 알아봤지만 만족스럽진 않았다.
일단 예제를 만들어서 테스트해보자.
준비1
Serialize할 수 있는 간단한 데이터 포맷 클래스를 만든다.
[Serializable]
public class PlayerInfo
{
public string name;
public int lives;
public float strength;
}
준비2
JsonHelper 클래스를 따로 만들어준다. JsonUtility의 가장 큰 단점이 배열을 받을 수 없다는 것인데 다음과 같이 JsonObject를 감싸는(JsonObject 배열을 가지는) Wrapper 클래스를 따로 만들어서 문제를 해결할 수 있다.
public static class JsonHelper
{
public static T[] FromJson<T>(string json)
{
Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
return wrapper.items;
}
public static string ToJson<T>(T[] array)
{
Wrapper<T> wrapper = new Wrapper<T>();
wrapper.items = array;
return JsonUtility.ToJson(wrapper);
}
public static string ToJson<T>(T[] array, bool prettyPrint)
{
Wrapper<T> wrapper = new Wrapper<T>();
wrapper.items = array;
return JsonUtility.ToJson(wrapper, prettyPrint);
}
[Serializable]
private class Wrapper<T>
{
public T[] items;
}
}
테스트 코드
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.Collections.Generic;
public class JsonTestWindow : EditorWindow {
[MenuItem("JSON/Test 1")]
static void Init()
{
JsonTestWindow window = (JsonTestWindow)EditorWindow.GetWindow(typeof(JsonTestWindow));
window.Show();
}
void OnGUI()
{
if (GUILayout.Button ("Save")) {
Save ();
}
if (GUILayout.Button ("Load")) {
Load ();
}
}
void Save()
{
//...아래에서
}
void Load()
{
//...//아래에서
}
}
Save()
void Save()
{
PlayerInfo[] playerInfo = new PlayerInfo[2];
playerInfo[0] = new PlayerInfo();
playerInfo[0].name = "12341234";
playerInfo[0].lives = 5;
playerInfo[0].strength = 25.0f;
playerInfo[1] = new PlayerInfo();
playerInfo[1].name = "1235235";
playerInfo[1].lives = 3;
playerInfo[1].strength = 30.2f;
string toJson = JsonHelper.ToJson(playerInfo, prettyPrint:true);
File.WriteAllText (Application.dataPath + "/Saves/data.json", toJson);
}
Load()
void Load()
{
string jsonString = File.ReadAllText (Application.dataPath + "/Saves/data.json");
var data = JsonHelper.FromJson <PlayerInfo>(jsonString);
foreach (var playerInfo in data) {
Debug.Log (playerInfo.name);
Debug.Log (playerInfo.lives);
Debug.Log (playerInfo.strength);
}
}
편의를 위해서 EditorWindow로 테스트 해보았다.
별다른 플러그인 없이 쉽게 구현이 가능하다는 장점이 있지만, 인덱싱이 안되고 데이터포맷을 미리 알지못하면 처리할 수 없다는 문제가 있으므로 간단한 데이터 저장용 외에는 활용하기 어려울 것 같다.
'아카이빙 > Unity3D' 카테고리의 다른 글
[Unity3D] Singleton 클래스 구현 (4) | 2017.04.15 |
---|---|
[Unity3D] 커스텀 에디터 - 반복문으로 오브젝트 생성 쉽게하기 (0) | 2017.04.14 |
[Unity3D] 커스텀 에디터(5) - EditorStyles (0) | 2017.04.14 |
[Unity3D] 커스텀 에디터(4) - GUILayout (0) | 2017.04.11 |
[Unity3D] 커스텀 에디터(3) - EditorWindow (0) | 2017.04.10 |