シリアライズオブジェクトで、初期値を変更しないで変数を使う

2024年6月14日

UnityのScriptableObjectを使って変数を初期化し、実行時にその初期値を維持する方法を紹介します。特に、ISerializationCallbackReceiverインターフェースを用いて、デシリアライズ時に初期値を再設定する方法を説明しています。これにより、実行時に変数が変更されても、再起動後に初期値に戻すことができます。

ScriptableObject とは?

ScriptableObject はシリアライズ可能な Unity 独自のクラスで、スクリプトインスタンスからは独立して大量の共有データを保存できます。ScriptableObject を使用すると、変更やデバッグの管理が容易になります。ゲーム内の各種システム間において、一定の水準で柔軟なコミュニケーションが簡単に確立されるようになるため、プロジェクト全体にわたるさまざまな事由における変更や採用に加えて、コンポーネントの再利用管理も簡単になります。

サンプル

using System;
using UnityEngine;

[CreateAssetMenu]
public class FloatVariable : ScriptableObject, ISerializationCallbackReceiver
{
    public float InitialValue;

    [NonSerialized]
    public float RuntimeValue;

    public void OnAfterDeserialize()
    {
        RuntimeValue = InitialValue;
    }

    public void OnBeforeSerialize() { }
}

このコードは、UnityのScriptableObjectを使用して、フロート型の変数を表すクラスを定義しています。

[CreateAssetMenu]属性は、Unityのエディター上でこのクラスのインスタンスを作成できるようにします。

ScriptableObjectを継承することにより、このクラスのインスタンスはUnityエディター上で生成でき、それらはアセットとしてプロジェクト内に保存されます。

ISerializationCallbackReceiverを実装することにより、インスタンスの状態をUnityのシリアライズ/デシリアライズプロセスに適応させることができます。

InitialValueは、変数の初期値を格納するフィールドです。

RuntimeValueは、実行時に変数の現在の値を格納するフィールドで、[NonSerialized]属性が付与されているため、シリアル化されないことが保証されています。

OnAfterDeserialize()メソッドは、デシリアライズ後に実行され、InitialValueからRuntimeValueを初期化します。

OnBeforeSerialize()メソッドは、シリアライズ前に実行される空のメソッドです。このメソッドは、このクラスがシリアライズされる前に、必要な前処理を実行するために使用されることがあります。しかし、このクラスでは何も行われていません。

テスト用のコード

using UnityEngine;

public class Test : MonoBehaviour
{
    [SerializeField]
    private FloatVariable floatVariable;

    void Start()
    {
        floatVariable.RuntimeValue++;
        Debug.Log(floatVariable.RuntimeValue);
    }
}

このコードは、UnityのMonoBehaviourを継承するクラスTestを定義しています。

[SerializeField]属性は、Unityのシリアル化システムがこのフィールドをシリアル化することを許可することを示します。

FloatVariableは、前の例で定義されたScriptableObjectのサブクラスであり、フロート型の変数を表します。

floatVariableは、FloatVariableのインスタンスを参照するためのフィールドです。

Start()メソッドは、MonoBehaviourのライフサイクルイベントであり、オブジェクトが最初にアクティブになったときに呼び出されます。

このメソッドでは、floatVariable.RuntimeValueの値を1つ増やし、増やした後の値をデバッグログに出力します。

つまり、FloatVariableオブジェクトがアクティブになるたびに、floatVariable.RuntimeValueの値が1つ増え、その後にログに表示されます。

CreateAssetMenuアトリビュートの使い方

UnityにおけるCreateAssetMenuは、Assetsメニューからスクリプトから生成したScriptableObjectや、その他のアセットを作成するための機能です。CreateAssetMenu属性を使用することで、アセットの作成を容易にすることができます。

以下は、CreateAssetMenu属性の基本的な使い方の例です。

using UnityEngine;

[CreateAssetMenu(fileName = "NewAsset", menuName = "MyAssets/NewAsset")]
public class MyScriptableObject : ScriptableObject
{
    public int myValue;
}

この例では、CreateAssetMenu属性を使用して、スクリプトでMyScriptableObjectを作成する方法を指定しています。fileNameパラメーターは、作成されるアセットのファイル名を指定し、menuNameパラメーターは、Assetsメニューに表示されるサブメニュー名を指定します。これにより、Assetsメニューから直接作成することができます。

上記の例を使用すると、以下の手順でアセットを作成することができます。

  1. Assetsメニューを開きます。
  2. MyAssetsサブメニューを選択します。
  3. NewAssetを選択します。
  4. 新しいMyScriptableObjectが作成されます。

CreateAssetMenu属性を使用することで、作成したいアセットを直接Assetsメニューから作成することができ、作業の効率化につながります。

ScriptableObject,Unity

Posted by hidepon