Amazon11/12まで!スマイルSale開催中!セール会場へ

UnityのScriptableObjectの使い方|データアセットの作成と参照の基本

UnityのScriptableObjectの使い方

UnityのScriptableObjectは、設定や定義データをアセットとして管理するために使えます。

アイテムの名前や基準価格など、複数のオブジェクトから同じ内容を参照したい場面に向いています。

最初に分けておきたいのは、共通の定義と、プレイヤーごとに変わる状態です。

アイテムの基本情報をScriptableObjectに置き、現在の所持数は別のデータで持つ、と考えると使い方を整理できます。

Unity 6.0の公式資料を2026年10月26日に照合しています。

今回、Unityでのコンパイル、再生、ビルドと画面確認は実施していません。

目次

MonoBehaviourとの違い

比較MonoBehaviourScriptableObject
今回の置き場所GameObjectのコンポーネントProject内のデータアセット
役割の例画面表示や動作を実行するアイテムの共通設定を持つ
参照の仕方必要なデータを参照して使う複数のコンポーネントから参照される

ScriptableObject自体をGameObjectにドラッグしてコンポーネントとして追加するわけではありません。

定義用スクリプトからアセットを作り、使う側のフィールドへそのアセットを割り当てます。

基本の位置づけはUnity公式のScriptableObjectガイドで確認できます。

スポンサーリンク

データの型を作る

Assets内にItemDefinition.csというファイルを作り、次のコードを保存します。

ファイル名とクラス名をそろえ、Consoleにコンパイルエラーがないことを確認してください。

using UnityEngine;

[CreateAssetMenu(fileName = "NewItem", menuName = "Game Data/Item")]
public class ItemDefinition : ScriptableObject
{
    [SerializeField] private string displayName = "新しいアイテム";
    [SerializeField] private int basePrice = 100;

    public string DisplayName => displayName;
    public int BasePrice => basePrice;
}

CreateAssetMenuは、この型のアセットを作るメニューを追加するための属性です。

SerializeFieldを付けたフィールドをInspectorで設定し、使う側には読み取り用のプロパティを公開しています。

これはゲーム全体の保存方式を完成させるコードではありません。

まず名前と価格という、小さい共通データを作って参照する例です。

Projectにデータアセットを作成する

  1. Projectウィンドウで保存先のフォルダーを開きます。
  2. Create → Game Data → Itemからアセットを作ります。
  3. アセット名をPotionなど、内容の分かる名前にします。
  4. InspectorでDisplay Nameを「回復薬」、Base Priceを100に設定します。

別のアイテムも必要なら、同じ型から別アセットを作れます。

たとえばKeyというアセットを作り、Display Nameを「古い鍵」にすれば、共通の項目構造で異なるデータを管理できます。

MonoBehaviourからアセットを参照する

Assets内にItemLabelExample.csを作り、次のコードを保存します。

空のGameObjectへ追加して、InspectorのItem欄へ先ほどのPotionアセットを割り当てます。

using UnityEngine;

public class ItemLabelExample : MonoBehaviour
{
    [SerializeField] private ItemDefinition item;

    private void Start()
    {
        if (item == null)
        {
            Debug.LogWarning("Itemにデータアセットを割り当ててください", this);
            return;
        }
        Debug.Log(item.DisplayName + " / 基準価格: " + item.BasePrice, this);
    }
}

再生時に「回復薬 / 基準価格: 100」と出れば、アセットを経由して値を読めています。

Item欄がNoneなら、スクリプトファイルそのものではなく、作成したデータアセットを割り当ててください。

表示先は画面上のラベルではなくConsoleです。

コードはStart()で一度ログを出すため、値を変更しても表示済みのログは更新されません。

再確認するときは再生を停止し、Potionの設定を変えてから再生し直し、新しいログを確認します。

共有データを書き換えると、参照先全体に影響する

同じアセットを2つのオブジェクトへ割り当てた場合、別々のデータがコピーされるのではなく、同じデータを参照します。

片方の処理がそのアセットの値を変えれば、もう片方から見える内容にも影響します。

敵の最大HPを共通の定義として持つのは自然ですが、現在HPまで同じアセットへ保存すると、敵同士で状態を共有してしまう設計になり得ます。

最大HPは定義、現在HPは生成した敵ごとのフィールド、と分けて持つ方法を検討します。

今回の例では、通常の利用コードから値を直接代入しにくい形にしています。

ただし、Inspectorでの変更や、クラス内部での変更まで禁止する仕組みではありません。

セーブデータの代わりになるとは限らない

ScriptableObjectのアセットを用意しても、ビルドしたゲームで実行中の変更が自動的にアセットファイルへ保存されるわけではありません。

ゲーム終了後も所持数や進行状況を残すなら、保存するデータと保存先を別に設計します。

Editor内でのアセット編集と、配布したビルドの実行時動作も区別してください。

検証後にデータが変わっていないか、バージョン管理の差分などで確認しておくと、調整用の値が意図せず残るのを見つけやすくなります。

公式資料では、EditorのInspectorで変更したアセットは、再生中でもディスクに保存されると説明されています。

GameObjectの一時的な変更と同じつもりで、停止すれば元に戻ると考えないでください。

一方、Editモードのスクリプトで値を書き換えるだけでは、自動保存されない場合があります。

独自のEditorツールで変更する場合は、EditorUtility.SetDirtyで変更を通知するなど、保存処理も必要です。

これはEditor用の処理であり、ビルドしたゲームのセーブ機能を追加するものではありません。

スポンサーリンク

作成メニューや参照欄が出ないとき

  • ScriptableObjectを継承しているか。
  • CreateAssetMenuを付けているか。
  • ファイル名とクラス名をそろえているか。
  • プロジェクト内のコンパイルエラーが残っていないか。
  • 参照するフィールドがUnityのシリアライズ対象、つまり保存・復元できるデータになっているか。

参照と保存の規則はUnity公式のスクリプトシリアライズ解説で確認できます。

小さなデータアセットを1つ作り、1つのコンポーネントから読む流れを完成させてから、項目や種類を増やすと管理しやすくなります。

この例で保存されるのはdisplayNameやbasePriceなどのフィールドです。

読み取り用のDisplayNameとBasePriceというプロパティ自体を保存する設計ではありません。

対象になるフィールドの条件はUnity公式のシリアライズ規則を参照してください。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

Unityのおすすめ書籍

開発PCの選び方

周辺機器の優先度

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

須澤 元貴のアバター 須澤 元貴 代表社員

MOTOKI合同会社 代表社員。
アニメ・映像業界とゲーム業界で、2D・UI・3D・アニメーション制作、映像編集、ツール制作に携わってきました。
現在はWordPressを中心にWebサイトの制作とカスタマイズを手がけています。
著書に『Unity デザイナーズ・バイブル』『Unityゲーム プログラミング・バイブル 2nd Generation』(ボーンデジタル)。
岡山県出身、埼玉県在住。

目次