ScriptableObjectとは?

ScriptableObjectは、Unityでデータを管理するための一つの方法です。

ゲームオブジェクトに依存しないデータを保持したい場合や、複数のゲームオブジェクト間でデータを共有したい場合に使用します。

イメージとしては、MonoBehaviourを継承したコンポーネントを作成した場合に含まれる、データ部分を抜き出したものです。

StartUpdateのようなライフサイクルイベントは持ちません。

ScriptableObjectの使用方法

1. 使用する前

敵を制御するために以下の様なコンポーネントを用意したとします。

using UnityEngine;

public class Enemy : MonoBehaviour
{
    [SerializeField] private string _name;
    [SerializeField] private int _hp;
    [SerializeField] private int _mp;
}

インスペクタ上は以下の様になります。

2. 派生クラスを作ってデータを移す

Enemyコンポーネントに含まれるSerializeFieldを抜き出して、ScriptableObjectクラスを継承した、

EnemyParameterクラスを作成します。

実行中に書き換えられたくないのでプロパティでgetterのみ追加しています。

using UnityEngine;

[CreateAssetMenu(menuName = "ScriptableObject/EnemyParameter")]
public class EnemyParameter : ScriptableObject
{
    [SerializeField] private string _name;
    [SerializeField] private int _hp;
    [SerializeField] private int _mp;

    public string Name => _name;

    public int Hp => _hp;

    public int Mp => _mp;
}

3. アセットを作成する

クラスを作成すると、UnityEditorのメニューから

AssetsCreateScriptableObjectEnemyParameter

を選択すると、EnemyParameterのアセットが作成されます。

適当に名前を変えましょう。

選択するとインスペクタ上で編集できるので適当に入力します。

MonoBehaviourを継承したコンポーネントを選択した時と同じですね。

4. ScriptableObjectを使用する

元のEnemyコンポーネントを以下の様に変更しました。

using UnityEngine;

public class Enemy : MonoBehaviour
{
    [SerializeField] private EnemyParameter _parameter;

    private void Awake()
    {
        Debug.Log(_parameter.Name);
    }
}

インスペクタ上は以下の様になり、前段で作ったEnemyParameterのアセットを渡せるようになります。

Enemyの性能を表すパラメータを一つのScriptableObjectにまとめることが出来ました。

CreateAssetMenuについて

先ほどのEnemyParameterクラスには、CreateAssetMenuという属性がついています。

[CreateAssetMenu(menuName = "ScriptableObject/EnemyParameter")]
public class EnemyParameter : ScriptableObject
{

こちらは、ScriptableObjectの派生クラスにつけている場合、

UnityEditorAssetsCreateメニュー以下にメニュー項目が追加され、

そこからアセットを生成することが出来るようになります。

以下の様にfileNameを指定することで、生成される時のファイル名を指定することも出来ます。

[CreateAssetMenu(menuName = "ScriptableObject/EnemyParameter", fileName = "EnemyParameter.asset")]
public class EnemyParameter : ScriptableObject
{

まとめ

今回は、Enemyコンポーネントに含まれるSerializeFieldScriptableObjectクラスを継承したEnemyParameterクラスに移行する方法について説明しました。

これにより、実行中に書き換えられないプロパティを持つ安全なデータ管理が可能となります。

ScriptableObjectを使用することで、プロジェクト中のアセットやパラメータを一元管理することができます。

例えば、敵ごとのSpriteや3Dモデルを持たせたり、種族設定のような別のScriptableObjectを参照することもできます。これにより、データを共通化し管理しやすくなるため、プロジェクトの複雑さを軽減し、コードの保守性を向上させることができます。

積極的にScriptableObjectを活用し、プロジェクトのデータ管理を効率化しましょう。