Unity研究所<Unityによるゲーム開発、映像開発>

Unity初心者おやじが綴るゲームで小遣い稼ぎできるようになるまでのブログ

Unity 小ネタ 実行時に追加したデータのJsonファイルへのデータ保存、読み込み 

前回は、Unityで作成したアプリの実行中に、データ入力用のUIフィールドを追加して、値を編集するようなものを作成したが、せっかく編集しても保存できなければ意味がないので、今回はJsonファイルへの保存、読み込みについて紹介する

 

〇前回の記事

harukichi.hatenadiary.jp

 

〇今回解説する機能の動作イメージ

①データ入力フィールドを動的に作成
②データを入力

③ファイルに保存ボタンを押すと、データが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を使用してというやり方もあるが、大量のデータや、動的に増えるデータの扱いには向いていないと思われるので、用途に合わせてどちらを使用するかを決めることになる

 

今回は以上