6. セットアップ手順(図解つき)
CGS をあなた自身のアセットに接続する任意のレシピ集 — オーディオミキサー、入力アクション、IL2CPP link.xml、Addressables。
この章の内容は、フレームワークを使い始めるうえで何ひとつ必須ではありません — すべては最初からそのまま動きます。ここでの手順は、フレームワークをあなたのアセットに接続するものです: あなたのオーディオミキサー、あなたの入力バインディング、あなたのビルド設定、そして(任意で)Addressables です。各手順は、上から下までそのままなぞれる完全なレシピになっています。
6.1 自分のオーディオミキサーを使う
オーディオサービスにはミキサーが同梱されているため、サウンドは最初から鳴ります。自分の Unity AudioMixer アセットを使う準備ができたら、そのミキサーには 2 つのものが必要です:
- Master の下に、正確に
Music、Sfx、Voiceと名づけた 3 つのグループ。 オーディオサービスは、各チャンネルを同じ名前のグループへルーティングします。 - 音量用の 4 つの公開 float パラメーター、名前は
MasterVolume、MusicVolume、SfxVolume、VoiceVolume。パラメーターを公開するには、グループを選択し、Inspector で Volume フィールドを右クリックして "Expose ... to script" を選びます。名前の変更は、ミキサーの Exposed Parameters ドロップダウンで行います。

Master の下に必須の 3 グループ(Music、Sfx、Voice)を持つ Audio Mixer ウィンドウ。Exposed Parameters ドロップダウン(右上)には、4 つの音量パラメーター MasterVolume、MusicVolume、SfxVolume、VoiceVolume が並んでいる必要があります。
次に、最初のシーンに置く小さなスクリプトで、あなたのミキサーをフレームワークに渡します。このスクリプトは、あなたのミキサーを土台に新しいオーディオサービスを構築して差し替えます:
using CommonGameSystem.Core;
using UnityEngine;
using UnityEngine.Audio;
[DefaultExecutionOrder(-100)] // swap before other scripts cache the audio service
public sealed class AudioSetup : MonoBehaviour
{
[SerializeField] private AudioMixer gameMixer; // assign your mixer in the Inspector
private void Awake()
{
var options = AudioOptions.Default;
options.Mixer = gameMixer;
// Used different parameter names? Point the service at them:
// options.masterParam = "MyMasterVol";
var previous = ServiceLocator.Resolve<IAudioService>() as System.IDisposable;
ServiceLocator.Replace<IAudioService>(new AudioService(
ServiceLocator.Resolve<IConfiguration>(),
ServiceLocator.Resolve<IEventBus>(),
ServiceLocator.Resolve<IObjectPoolService>(),
ServiceLocator.Resolve<ITimeService>(),
options));
previous?.Dispose(); // removes the old service's hidden helper object
}
}
オプションメニューの音量スライダーは、ミキサーと直接ではなく、設定サービスと対話します。Get<AudioSettings>() で現在のグループを読み取り、フィールドを変更し、Set(...) に続けて FlushPending<AudioSettings>() を呼びます。フラッシュは変更を保存し、新しい音量を即座にミキサーへ反映します。完全なリファレンス: Audio と Configuration。
6.2 自分の入力アクションを接続する
入力サービスは、あなたが作成する Unity Input System アセット(.inputactions ファイル)を読み取ります — フレームワークが同梱するのは空のプレースホルダーだけです。アクションマップ("Gameplay"、"Menu")とその中のバインディングを定義するのは、あなたのアセットです。
- アセットを作成します: Project ウィンドウで右クリックし、Create > Input Actions を選びます。
GameInputのような名前をつけます。 - アセットを開き、アクションマップとアクションを追加します — 例えば "Move" と "Jump" を持つ "Gameplay" マップです。
- フレームワークの UI パネルスタックを自動入力切り替えつきで使うなら、正確に
ui.panelとui.modalという名前のマップも 2 つ追加してください。パネルスタックは、メニューが開いている間これらを有効化します。名前は大文字と小文字を区別します。

"Gameplay" マップと、パネルスタック用の 2 つのマップ ui.panel・ui.modal(ハイライト表示)を持つアセットを表示した Input Actions エディタ — これが目指す完成形です。フレームワークがこのアセットを編集することはありません — デッドゾーン、ホールド、バインディングは完全にあなたの管理下に残ります。
最初のシーンに置く 1 つのスクリプトでアセットを接続します。このスクリプトは、あなたのアセットを土台に入力サービスを再構築し、メニューナビゲーションもそれを使うようにパネルスタックを再構築します:
using CommonGameSystem.Core;
using UnityEngine;
using UnityEngine.InputSystem;
[DefaultExecutionOrder(-100)] // swap before other scripts cache these services
public sealed class InputSetup : MonoBehaviour
{
[SerializeField] private InputActionAsset actions; // your .inputactions asset
private void Awake()
{
var source = new HardcodedInputKeyMapSource(actions);
var bus = ServiceLocator.Resolve<IEventBus>();
var time = ServiceLocator.Resolve<ITimeService>();
var oldInput = ServiceLocator.Resolve<IInputService>() as System.IDisposable;
var oldUi = ServiceLocator.Resolve<IPanelStack>() as System.IDisposable;
ServiceLocator.Replace<IInputKeyMapSource>(source);
var input = new DefaultInputService(source, bus);
ServiceLocator.Replace<IInputService>(input);
ServiceLocator.Replace<IPanelStack>(
new PanelStack(bus, input, time, PanelStackOptions.Default));
oldInput?.Dispose();
oldUi?.Dispose();
}
}
パネルスタックを使わない場合は、2 つの IPanelStack 行と oldUi の行を削除してください。あなたのスクリプトが独自のアセンブリ定義に属している場合、このスクリプトには CommonGameSystem.Input、CommonGameSystem.UI、Unity.InputSystem への参照が必要です — 第 7.1 章の表を参照してください。
再起動をまたいで維持されるリバインド。 プレイヤーがコントロールを割り当て直したら(サービスの対話的リバインドが、新しいキーを押す手順をプレイヤーに案内します)、その後に SaveBindingOverrides() を呼んでください。オーバーライドは Unity の PlayerPrefs に保存されます。起動時に一度 LoadBindingOverrides() を呼んで復元し、「デフォルトに戻す」ボタンには ResetBindingOverrides() を使います。完全なリファレンス: Input。
6.3 IL2CPP ビルド: セーブ用クラスを生かしておく (link.xml)
IL2CPP ビルドは、ゲームを小さくするために、未使用に見えるコードをストリップします。シリアライズを通じてのみ生成されるクラス — セーブデータ、カスタム設定グループ、シリアライズするイベントクラス — は、ストリッパーには未使用に見えてしまいます。その結果: エディタではセーブが機能するのに、ビルドしたゲームでは静かに壊れます。
修正は link.xml ファイルです。これは Unity に「これらは決してストリップするな」と伝えます。Assets/ 配下の任意の場所(フォルダのルートで構いません)に、正確に link.xml という名前のファイルを作成し、自分のクラスを列挙します:
<linker>
<assembly fullname="Assembly-CSharp">
<type fullname="MyGame.PlayerSave" preserve="all"/>
<type fullname="MyGame.OptionsSave" preserve="all"/>
</assembly>
</linker>
このファイルはどこに置く?
Assets/link.xmlとして保存してください。各<type>行は、あなた自身のクラスを完全な名前空間つきで指定します。"Assembly-CSharp" はプロジェクトスクリプトのデフォルトアセンブリです — コードがアセンブリ定義を使っている場合は、そのアセンブリ名を代わりに使ってください。
経験則:
Save<T>(...)に渡すクラス、または設定グループとして保存するクラスごとに、<type>行を 1 つ追加します。fullnameは名前空間を含むクラス名です。ここでのタイプミスは静かに失敗するので、コードからコピーしてください。- フレームワーク自身の型はすでに保護されています。列挙するのはあなたのクラスだけです。
- これは IL2CPP ビルドだけに影響します。エディタと Mono ビルドはストリップを行わないため、このバグは実ビルドまで潜伏します。
6.4 Addressables のセットアップ(アドレスでアセットをロードする場合のみ)
Unity の Addressables パッケージを必要とするサービスは 2 つです: アセットプロバイダー(プレハブ、スプライト、オーディオをテキストのアドレスでロードし、参照カウントを自動管理)と、Addressable シーンサービス(Addressables からの加算シーン)です。どちらも使わないなら、この節はスキップしてください — フレームワークはこのパッケージなしでも問題なく動きます。
- Window > Package Manager の Unity Registry タブから Addressables(
com.unity.addressables)をインストールします。 - Window > Asset Management > Addressables > Groups を開き、Create Addressables Settings を一度クリックします。
- 実行時にロードしたいアセットを選択し、Inspector 上部の Addressable にチェックを入れます。チェックボックスの隣のテキストフィールドが、そのアセットのアドレスです。
- そのアドレス文字列が、フレームワークに渡すキーになります:
await assets.LoadAsync<GameObject>("characters/player")。
エディタでは、Play モードは Addressable アセットをプロジェクトから直接ロードするので、自由にイテレートできます。プレイヤービルドを出荷する前に、Groups ウィンドウから Addressables コンテンツを一度ビルドしてください(Build > New Build > Default Build Script)。パッケージがインストールされていれば、両サービスは起動時に自動で登録されます — フレームワーク側の追加セットアップはありません。