mcpField
U
unity-scriptableobjects

unity-scriptableobjects

github.com/gamedev-skills開発5.4k6.3k 回インストール1 日前に更新
リポジトリ

unity-scriptableobjects について

unity-scriptableobjectsは、Unity 6.3 LTS向けのアーキテクチャスキルです。ScriptableObjectアセットで共有データを管理し、デザイナーが編集する設定、イベントチャンネル、ランタイムレジストリを通じてシステムを疎結合にします。

主な機能

  1. 01共有データアセットの作成
  2. 02イベントチャンネルによる疎結合化
  3. 03ランタイムオブジェクトレジストリの構築
  4. 04アセット参照による設定共有
  5. 05実行時変更のリセット処理

活用シーン

  1. 01武器の性能やレベルデータの設定
  2. 02イベントによるシステム間連携
  3. 03アクティブなオブジェクト群の追跡
  4. 04共有データ用シングルトンの回避

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill unity-scriptableobjects

インストール後、Claude Code で/unity-scriptableobjectsを入力して読み込まれたか確認します。

同梱ファイルreferences/event-channels.md

詳細

Unity ScriptableObject アーキテクチャ

ScriptableObject アセットを使って共有データを保存し、Unity 6.3 LTS でシステム間の依存関係を切り離します。設定、イベントチャンネル、レジストリを、シーンやシングルトンに直接組み込むのではなく、プロジェクトアセットとして管理できます。対象は Unity 6.3 LTS (6000.3) です。

使用する場面

  • デザイナーが編集できる設定(武器のステータス、レベルデータなど)が必要な場合、無関係なシステム間で値を共有する場合、イベントチャンネルを介して送信側とリスナーを切り離す場合、または static/シングルトンのマネージャーを使わずにアクティブなオブジェクトのランタイムレジストリを構築する場合に使用します。
  • *.asset データファイルがあり、それを : ScriptableObject クラスで扱うプロジェクトで使用します。

使用しない場面: GameObject ごとに異なるインスタンス単位のランタイム状態(これは MonoBehaviour に持たせます)。ScriptableObject アセットは、参照するすべてのオブジェクトで 共有 されます。プレイヤーの進行状況をディスクに保存する場合は save-systems を使用してください。アセットにする必要のない単純な DTO は [System.Serializable] クラスにできます。

基本的なワークフロー

  1. クラスを定義します。 ScriptableObject を継承し、[CreateAssetMenu] を付けて、デザイナーが Assets メニューからインスタンスを作成できるようにします。
  2. Project ウィンドウで .asset インスタンスを 1 つ以上作成します。 それぞれは [SerializeField] フィールドから参照される、名前付きの共有データです。
  3. コピーせずに参照します。 MonoBehaviour はアセットへの参照を保持します。すべての参照元が同じデータを参照するため、アセットを変更するとすべての利用側に反映されます。
  4. 依存関係を切り離すには、 シグナル と 共有変数 を ScriptableObject としてモデル化します。たとえば、HUD が読み取り、プレイヤーが書き込む「FloatVariable」や、プレイヤーが発火し、多数のシステムがリッスンする「イベントチャンネル」です。どちら側も相手を参照しません。
  5. ランタイム中にアセットを変更する場合は、 OnEnable でランタイム変更をリセットします。ランタイム中にエディターで行った編集はアセットに保持されるため、「プレイ後に値が変わった」という問題がよく発生します。
  6. 確認します。 Play モード中にアセットの値を調べ、利用側が反応することを確認します。

パターン

1. 設定/データアセット
using UnityEngine;

[CreateAssetMenu(fileName = "WeaponData", menuName = "Game/Weapon Data", order = 0)]
public class WeaponData : ScriptableObject
{
    public string displayName = "Pistol";
    public int    damage = 10;
    public float  fireRate = 0.25f;
    public GameObject projectilePrefab;
}
public class Weapon : MonoBehaviour
{
    [SerializeField] private WeaponData data;   // assign the shared asset in the Inspector
    private void Fire() => Debug.Log($"{data.displayName} for {data.damage}");
}
2. 共有ランタイム変数(生成側と利用側を切り離す)
[CreateAssetMenu(menuName = "Game/Float Variable")]
public class FloatVariable : ScriptableObject
{
    [SerializeField] private float initialValue;
    [System.NonSerialized] public float runtimeValue;   // not saved to the asset

    private void OnEnable() => runtimeValue = initialValue;  // reset each play session
}
// Player writes playerHealth.runtimeValue; the HUD reads it — neither references the other.
3. ランタイムでのインスタンス作成(ディスク上のアセットではない)
// For transient SO data you build in code (e.g. a generated config).
var temp = ScriptableObject.CreateInstance<WeaponData>();
temp.damage = 25;
// ...use temp...  Destroy(temp);   // clean up runtime-created instances

注意点

  • ランタイム中に SO を編集すると、エディターに変更が保持されます。 Play 中に変更した値は、停止後もアセット上で変更されたままです。変更可能なランタイム状態は [NonSerialized] フィールドに保持し、OnEnable でリセットしてください。そうしないと思わぬ結果になります。(ビルド ではアセットの編集内容は起動をまたいで保持されません。)
  • Domain Reload を無効にすると、OnEnable によるリセットは実行されません。 Enter Play Mode Options を有効にし、Reload Domain をオフにした場合(Unity 6.3 LTS の高速イテレーション設定)、すでに読み込まれている SO は Play を押しても 再作成されません。そのため OnEnable は呼び出されず、runtimeValue は前回のセッションの値を保持します。OnEnable だけに頼るのではなく、ISerializationCallbackReceiver またはシーン読み込みフックから明示的にリセットしてください。
  • オブジェクトごとの状態を期待しないでください。 すべての参照は 同じ アセットを指します。2 体の敵がそれぞれ異なる現在 HP を持つ必要がある場合、HP は共有 SO ではなく MonoBehaviour に保存してください。
  • フレーム単位のライフサイクルはありません。 ScriptableObject には OnEnable/OnDisable/OnDestroy がありますが、Update はありません。フレームごとのコールバックを期待しないでください。
  • SO をセーブファイルとして使わないでください。 SO は作成・編集用のアセットであり、ランタイムの永続化用ではありません。進行状況の保存には save-systems を使用してください。
  • CreateInstance オブジェクトのリークに注意してください。 ランタイムで作成したインスタンスは通常の C# オブジェクトのようにガベージコレクションされません。不要になったら Destroy してください。

参考資料

  • イベントチャンネルパターン(GameEvent SO とリスナー、型安全なペイロード)およびランタイムセット/レジストリ(アクティブな敵の共有リスト)については、references/event-channels.md を参照してください。
  • 主なドキュメント:Unity Manual「ScriptableObject」(/Manual/class-ScriptableObject.html)、ScriptReference/ScriptableObject、ScriptReference/CreateAssetMenuAttribute。

関連スキル

  • unity-csharp-scripting — これらのアセットを使用する MonoBehaviour。
  • save-systems — 状態をディスクに永続化します(SOs の用途ではありません)。
  • card-game / rpg / survival-crafting — SO 主導のデータを活用するジャンルです。

コメント