【Unity】JSON形式でファイルを読み書きする

こじゃらこじゃら

ゲーム中のデータを手軽にセーブ・ロードする方法を知りたいの。

このはこのは

JSON形式にシリアライズすればセーブができるわ。ロード時は逆の操作をやってあげれば良いの。

スクリプト中で扱うデータをJSON形式で読み書きする方法の解説記事です。

ゲーム中のデータとJSON形式との相互変換は、Unityが提供するJsonUtilityクラスを使えば簡単に実現できます。

ファイルとしての読み書きは複数手段がありますが、ファイルシステムが使える環境なら.NETのFileクラスを用いるのが簡単です。

本記事ではUnityのJsonUtilityクラスと.NETのFileクラスを用いて、スクリプトで扱うオブジェクトをJSON形式のデータとして読み書きする方法を解説していきます。

スポンサーリンク

JsonUtilityクラス

Unity5.3より追加されたUnity標準のJSONデータを扱うクラスです。

オブジェクトをJSON形式のテキストにシリアライズするToJsonメソッド、逆にJSON形式のテキストからオブジェクトにデシリアライズするFromJsonメソッドがあります。

次のようなコードでオブジェクトとJSONテキストとの相互変換ができます。

オブジェクトからJSONへの変換

MyClass obj = new MyClass();

・・・(中略)・・・

// JSON形式にシリアライズ
var json = JsonUtility.ToJson(obj);

JSONからオブジェクトへの変換

string json;

・・・(中略)・・・

// JSONからオブジェクトにデシリアライズ
var obj = JsonUtility.FromJson<MyClass>(JsonText);

JSON形式のデータはstring型の文字列となります。

JsonUtilityクラスのより詳細な使い方については、以下記事をご覧ください。

Fileクラス

.NETが提供するFileクラスでは、文字列データを読み書きするメソッドが提供されています。

文字列データのファイル保存にはFile.WriteAllTextメソッド、ファイル読み込みにはFile.ReadAllTextメソッドを使います。

実際の使用例は以下のようになります。

ファイルへの保存

string dataPath;
string json;

・・・(中略)・・・

// JSONデータをファイルに保存
File.WriteAllText(dataPath, json);

ファイルからの読み込み

string dataPath;

・・・(中略)・・・

// JSONデータとしてデータを読み込む
string json = File.ReadAllText(dataPath);

Json形式でセーブデータの読み書きをする

以上を踏まえて、実際にJSONデータとしてファイルに対して読み書きを行ってみたいと思います。

サンプルスクリプト

以下、ゲームオブジェクトのワールド位置を読み書きするサンプルスクリプトです。

JsonSerializationTest.cs
using System.IO;
using UnityEngine;

// JSON形式のデータ読み書きテスト
public class JsonSerializationTest : MonoBehaviour
{
    // 位置データ
    [System.Serializable]
    private struct PositionData
    {
        public Vector3 position;
    }

    // ファイルパス
    private string _dataPath;
    private void Awake()
    {
        // ファイルのパスを計算
        _dataPath = Path.Combine(Application.persistentDataPath, "position.json");
    }
    private void Update()
    {
        // 1キー押下で現在位置をセーブする
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            OnSave();
        }

        // 2キー押下で現在位置をロードする
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            OnLoad();
        }

        // 方向キーで移動できるようにしておく
        transform.position = transform.position + new Vector3(
            Input.GetAxis("Horizontal"),
            Input.GetAxis("Vertical")) * Time.deltaTime;
    }

    // JSON形式にシリアライズしてセーブ
    private void OnSave()
    {
        // シリアライズするオブジェクトを作成
        var obj = new PositionData
        {
            position = transform.position
        };

        // JSON形式にシリアライズ
        var json = JsonUtility.ToJson(obj, false);

        // JSONデータをファイルに保存
        File.WriteAllText(_dataPath, json);
    }

    // JSON形式をロードしてデシリアライズ
    private void OnLoad()
    {
        // 念のためファイルの存在チェック
        if (!File.Exists(_dataPath)) return;

        // JSONデータとしてデータを読み込む
        var json = File.ReadAllText(_dataPath);

        // JSON形式からオブジェクトにデシリアライズ
        var obj = JsonUtility.FromJson<PositionData>(json);

        // Transformにオブジェクトのデータをセット
        transform.position = obj.position;
    }
}

このスクリプトをJsonSerializationTest.csという名前で保存し、対象のゲームオブジェクトにアタッチすると機能するようになります。

実行結果

方向キーでオブジェクトを移動させ、「1」キーで現在位置をJSONファイルに保存、「2」キーでJSONファイルから現在位置を読み込んでTransformにセットする挙動になります。

なお、JSON形式で保存するファイルは、Application.persistentDataPathが指し示すディレクトリ配下にposition.jsonとして置くようになっています。

パスは各プラットフォームによって異なります。各プラットフォーム毎のパスは以下リファレンスをご覧ください。

position.jsonを開くと、以下のようにデータが格納されていることと思います。

{"position":{"x":-0.014371572993695736,"y":2.6874682903289797,"z":0.0}}

さいごに

今回は、JsonUtilityクラスとFileクラスによるデータ読み書きの方法をご紹介させていただきました。

Unity標準以外の機能を視野に入れると、ほかにも様々な方法で同様の目的が実現できます。

JSONというテキスト形式として扱うことで、デバッグが容易になる、サーバーとのデータのやり取りがしやすくなるといったメリットも存在します。

ぜひ活用を検討してみてください。

関連記事

参考サイト

スポンサーリンク