いんでぃーづ

ゲームいろいろ、いろいろ自由

Unity : 不変データはScriptableObject を使って管理するとドヤ顔できるかもしれない

目次


敵の攻撃力や防御力など、「ゲーム全体で共通かつ不変」なデータを持たせたい場合は数多くあります。

そんな時つい、やってしまいがちなのが、プレハブ自体に値を持たせる方法。

f:id:sugar_affordance:20160625233559p:plain:w400

こんなふうに持たせてしまうと、Instantiateするたびにこれらの変数がメモリに確保されてしまいます。

でもスクリプトにconst変数で持たせるのもツライなあ、インスペクターで設定したいなあ...そんなふうに悩んでいたことも、あったようななかったような。

解はひとつ!

ScriptableObject ならインスペクターで設定できつつメモリは一箇所で済みます

http://docs.unity3d.com/ja/current/Manual/class-ScriptableObject.html


ScriptableObjectを作成する

まず、とにもかくにもScriptableObjectを作ってみましょう。

以下のようなスクリプトを作成します。 Power, Speed, Lifeがインスペクターで設定できる変数です。

[CreateAssetMenu]
public class EnemyDataTable : ScriptableObject {

    public int Power, Speed, Life;

}

MonoBehaviour でなく、ScriptableObjectを継承すること!
また、CreateAssetMenuというAttributeがついてますが、これをつけることにより、メニューからScriptableObjectアセットが作成可能になります。

f:id:sugar_affordance:20160625233602p:plain:w400

Assets > Create から、作成したクラス名が選択できるようになってますね。

ポチっとな。

f:id:sugar_affordance:20160625233606p:plain:w500

プロジェクトビューで見ると、Assetが作成されてます。

ScriptableObject のデータを設定する

まずScriptableObjectのデータをインスペクターで設定します。

f:id:sugar_affordance:20160625233609p:plain:w400

次に、値を参照したいスクリプトで、作成したScriptableObjectクラスをメンバとして持ちます。

public class Enemy : MonoBehaviour {

    [SerializeField]
    EnemyDataTable data;         // 作成したScriptableObjectクラス

}

最後に、作成したScriptableObjectをインスペクタでメンバ変数として設定します。

f:id:sugar_affordance:20160625233611p:plain:w400

値を参照するときは以下のように、プロパティとして参照します。

void Start() {
     Debug.Log(""+data.Life);
}

これでメモリを節約しつつ、共有データを持てるんです!

データを書き換えられないようにスクリプトを修正する

現状だとデータを public で持っているので、他のスクリプトから書き換えられてしまいますね。
それを防ぐには、スクリプトで以下のように public な getter を作成し、シリアライズ可能な変数にアクセスします。

[CreateAssetMenu]
public class EnemyDataTable : ScriptableObject {

    [SerializeField]
    int power, speed, life;

    public int Power {
        get {
            return power;
        }
    }
    public int Speed {
        get {
            return speed;
        }
    }

    public int Life {
        get {
            return life;
        }
    }
}

こうすることでインスペクタから設定しつつ、スクリプトから書き換えるのを防ぐことができます。


便利ですねえ。ScriptableObject。
これでもうちょっと作り方が簡単だったらね...という方は → ここ


“Unity” and Unity logos are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere, and are used under license.


免責事項

当サイトの広告バナー、リンクによって提供される情報、サービス内容について、当サイトは一切の責任を負いません。

また、当サイトの情報を元にユーザ様が不利益を被った場合にも、当サイトは一切の責任を負いません。

すべて自己責任でお願いします。