【Unity】JsonUtilityを使ってオブジェクト(インスタンス)を保存する方法

2023年10月14日

UnityのJsonライブラリとPlayerPrefsを使ったインスタンスデータの保存方法について確認しましょう

シリアライズとデシリアライズ

シリアライズ

シリアライズとは、複数の並列データを直列化して送信すること。
具体的には、メモリ上に存在する情報を、ファイルとして保存したり、ネットワークで送受信したりできるように変換すること。オブジェクト(インスタンス)を保存できるようにテキスト(JSONなど)やバイナリにデータ化すること

デシリアライズ

既にファイルとして存在しているデータや、一旦シリアライズされたデータがネットワークから送られてきた際に、プログラムで扱えるようにする作業。オブジェクト(インスタンス)を復元する

サンプルの作成

次のような商品クラスを作成します

class Product
{
    // 商品名
    public string Name;

    // 賞味期限
    public string Expiry;

    // 大きさの種類
    public string[] Sizes;
}

クラスからインスタンスを作成し、データをセットしましょう

必要に応じて、クラスを作成します。後半に全てのコードを記載しています。

// 名称
product.Name = "Apple";
// 賞味期限
product.Expiry = new DateTime(2020, 1, 28).ToShortDateString();
// 大きさの種類
product.Sizes = new string[] { "Small", "Big" };

インスタンスをシリアライズ化します

必要に応じて、参照の追加、usingを追加します。

シリアライズ化の属性をつけます
Unityの場合、Product productのようにクラスの宣言時にインスタンス化することができます。

// 商品のインスタンスをインスペクターに表示させます。productは、Product型のフィールドになります。
[SerializeField]
Product product;

// 商品クラスをシリアライズ
[Serializable]
class Product
{
    // 商品名
    public string Name;

    // 賞味期限
    public string Expiry;

    // 大きさの種類
    public string[] Sizes;
}

Jsonフォーマットに変換します

必要に応じて、usingを追加します。
ファイルに書き出されていることを確認します。

ToJsonメソッドの第2引数は、見やすくフォーマットするスイッチです

jsonString = JsonUtility.ToJson(product, true);

jsonStringには次のようなフォーマットで代入されます。

{
    "Name": "Apple",
    "Expiry": "1/28/2020",
    "Sizes": [
        "Small",
        "Big"
    ]
}

コンソール画面に出力します

確認のため、画面にも表示します。

Debug.Log(jsonString);

ファイルの保存します

PlayerPrefsクラスのSetStringメソッドでファイルに保存します。

PlayerPrefs.SetString("Product", jsonString);
PlayerPrefs.Save();

ファイルから読み込みます

保存されたJSON文字列を読み取ります

string loadProductString = PlayerPrefs.GetString("Product");

JSON文字列から、オブジェクトを復元します

Product loadProductInstance = JsonUtility.FromJson<Product>(loadProductString);

復元されたオブジェクトの表示確認

Debug.Log($"名前:{loadProductInstance.Name}");
Debug.Log($"日付:{loadProductInstance.Expiry}");

foreach (var size in loadProductInstance.Sizes)
{
    Debug.Log($"サイズ:{size}");
}

全てのコード

このコードをテスト用のゲームオブジェクトにアタッチして試してみます

using System;
using UnityEngine;

public class Sample : MonoBehaviour
{
    // 商品のインスタンスをインスペクターに表示させます
    [SerializeField]
    Product product;

    [Serializable]
    // 商品クラスをシリアライズ
    class Product
    {
        // 商品名
        public string Name;

        // 賞味期限
        public string Expiry;

        // 大きさの種類
        public string[] Sizes;
    }

    string jsonString;

    void Start()
    {
        // 名称
        product.Name = "Apple";

        // 賞味期限
        product.Expiry = new DateTime(2020, 1, 28).ToShortDateString();

        // 大きさの種類
        product.Sizes = new string[] { "Small", "Big" };

        // ToJsonメソッドの第2引数は、見やすくフォーマットするスイッチです
        jsonString = JsonUtility.ToJson(product, true);

        // 画面に出力
        Debug.Log(jsonString);

        // ファイルに保存
        PlayerPrefs.SetString("Product", jsonString);
        PlayerPrefs.Save();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 保存されたJSON文字列を読み取り
            string loadProductString = PlayerPrefs.GetString("Product");

            // JSON文字列からオブジェクトを復元
            Product loadProductInstance = JsonUtility.FromJson<Product>(loadProductString);

            // 復元の確認
            Debug.Log($"商品名:{loadProductInstance.Name}");
            Debug.Log($"賞味期限:{loadProductInstance.Expiry}");

            foreach (var size in loadProductInstance.Sizes)
            {
                Debug.Log($"大きさの種類:{size}");
            }
        }
    }
}

参考

C#,Unity

Posted by hidepon