前回は、Unityで作成したアプリの実行中に、データ入力用のUIフィールドを追加して、値を編集するようなものを作成したが、せっかく編集しても保存できなければ意味がないので、今回はJsonファイルへの保存、読み込みについて紹介する
〇前回の記事
〇今回解説する機能の動作イメージ
①データ入力フィールドを動的に作成
②データを入力
③ファイルに保存ボタンを押すと、データがJsonファイルに保存される
④データを消去して、データ読み込みボタンを押すとJsonファイルからデータを読み込んで、フィールドが復元される
ちなみに、Jsonファイルの中身は下記の通り
{
"dataSets": [
{
"number": 0,
"data": [
1,
2,
3
],
"isCheckOn": false
},
{
"number": 1,
"data": [
4,
5,
6
],
"isCheckOn": false
},
{
"number": 2,
"data": [
7,
8,
9
],
"isCheckOn": false
}
]
}
今回のサンプルでのデータ形式は上記からもわかる通り、下記のデータが一塊となっている(以下データセットと呼ぶ)
int number
int data[3]
bool isCheckOn
ここまでなら簡単だったのだが・・・・
実行時に動的に上記のデータセットを追加したいとなると、データセットの配列をJsonファイルに保存する必要が出てくる
今回はこの点の実装にかなり苦労した(知識がなかっただけだが・・・)
◇やることの概要
◆保存の手順
①保存したいデータのクラスを作る 頭に[System.Serializable]をつける必要あり
②JsonUtilityを使用してクラス内のデータを文字列に変換
③ファイルに保存
◆読み込みの手順
①ファイルを開く
②ファイルから読み込んだ文字列を、JsonUtilityを使用してクラス形式に変換
③クラス内のデータをUIに反映
◇詳細
〇基本のJsonファイルへのデータの保存
using System.IO;
//基本的にはJsonUtilityというものが用意されているので、これを使用するだけ
//第一の引数が保存したいクラスデータ、第二引数はファイルの中で改行するかどうか
string jsonstr = JsonUtility.ToJson(dataSet,true);
//ここからは一般的なファイルの保存
StreamWriter writer;
writer = new StreamWriter(Application.dataPath + "/DataSet.json", false);
writer.Write(jsonstr);
writer.Flush();
writer.Close();
〇読み込み
string datastr = "";
StreamReader reader;
reader = new StreamReader(Application.dataPath + "/DataSet.json");
datastr = reader.ReadToEnd();
reader.Close();
//ファイルから読み込んだ文字列をJsonUtilityにてクラス形式に変換
dataSet=JsonUtility.FromJson<DataSet>(datastr);
〇上記で保存に使用したクラスデータ
[System.Serializable] ⇐こいつを記載すると保存の対象になる
public class DataSet
{
public int number;
public int data=new int[3];
public bool isCheckOn;
}
〇上記のクラスデータの配列の保存の手順
上記の基本クラスの配列をデータとしたクラスを作成し、こちらをJsonUtilityで変換する
◎注意点
・MonoBehaviourを継承しているクラスは変換できない
・UnityのUIが変数として含まれていても変換はされるが、Jsonファイルの中がごちゃごちゃになる印象
直接Jsonふぁるの中身を修正したいような場合に困りそう。
今回はデータのみのクラスを作成した
//配列のクラス
[System.Serializable]
public class SaveDataArray
{
public DataSet dataSets;
}
//具体的な処理//////////////////////////////////
//保存
public void OnSaveButtonDown()
{
//クラスのインスタンスを用意(やらないとインスタンスがないエラーが出る)
//データセットの個数分割り付ける
saveDataArray = new SaveDataArray();
saveDataArray.dataSets = new DataSet[DataSetList.Count];
//生成されているデータの配列から、保存用のクラスのデータ配列にコピー
for (int i = 0; i < DataSetList.Count; i++)
{
saveDataArray.dataSets[i] = DataSetList[i].GetComponent<DataSetManager>().dataSet;
}
//データセットの配列クラスをJsonUtilityで文字列に変換
string jsonstr = JsonUtility.ToJson(saveDataArray,true);
//ファイルに保存
StreamWriter writer;
writer = new StreamWriter(Application.dataPath + "/DataSet.json", false);
writer.Write(jsonstr);
writer.Flush();
writer.Close();
}
//読み込み
public void OnLoadButtonDown()
{
//ファイルから読み込み
string datastr = "";
StreamReader reader;
reader = new StreamReader(Application.dataPath + "/DataSet.json");
datastr = reader.ReadToEnd();
reader.Close();
//JsonUtilityでデータセットの配列クラスをクラスデータに変換
saveDataArray=JsonUtility.FromJson<SaveDataArray>(datastr);
//UIを生成してデータを反映
for (int i = 0; i < saveDataArray.dataSets.Length; i++)
{
GameObject tempObj = Instantiate(DataSetPrefab, parent);
DataSetList.Add(tempObj);
tempObj.GetComponent<DataSetManager>().dataSet = saveDataArray.dataSets[i];
tempObj.GetComponent<DataSetManager>().UpdateData();
}
}
〇まとめ
・JsonUtilityを使用すると、クラスのデータを文字列に変換、復元できる
・JsonUtilityが使用できるクラスは、MonoBehaviourの継承NG
・保存するクラスの定義の頭に[System.Serializable]
・データの配列も使用可能
今回の例は、基本のデータセットと、このデータセットの配列を作成し、配列の方をJsonUtilityにて変換してファイルに保存した
Unityでのデータの保存は、PlayerPrefを使用してというやり方もあるが、大量のデータや、動的に増えるデータの扱いには向いていないと思われるので、用途に合わせてどちらを使用するかを決めることになる
今回は以上