Bootstrap
フレームワークの自動起動 — 最初のシーンがロードされる前に、23 のサービスすべてを依存順に登録します。
フレームワークの自動起動 · 最初のシーンがロードされる前に一度だけ実行 · 23 のサービスすべてを登録 · 差し替え不可
概要
Bootstrap はフレームワークの自動起動ルーチンです。23 のサービスすべてを依存順に登録し、前回の Play セッションから残った内部 GameObject を削除し(エディタで Domain Reload が無効な場合にのみ関係します)、Logger をウォームアップします。あなたがこれを呼び出すことはありません — Unity が最初のシーンのロード前に自動で呼び出し、Play セッションごとにちょうど一度だけ実行されます。
起動が完了すると、Unity Console に次の行が表示されます:
bootstrap complete (v2.1.0, 23 services)
この行が表示されていれば、フレームワークは起動済みで、すべてのサービスが使用可能です。
簡単な使用例
実際の使い方として最も一般的なのは、Bootstrap を直接呼び出すことは決してないという点です。自分の Awake が実行される頃には、すべてのサービスはすでに登録済みです — 解決(resolve)して使うだけです。
using CommonGameSystem.Core;
using UnityEngine;
[DefaultExecutionOrder(100)] // Run AFTER framework startup — the attribute goes on the class
public class GameController : MonoBehaviour
{
void Awake()
{
// Bootstrap.Run has already fired. All services are registered.
// Resolve once and cache the references.
var time = ServiceLocator.Resolve<ITimeService>();
var pool = ServiceLocator.Resolve<IObjectPoolService>();
var bus = ServiceLocator.Resolve<IEventBus>();
// DeltaTime is a method: you pick the clock you want.
Debug.Log($"Gameplay: {time.DeltaTime(Clock.Gameplay)}, " +
$"unscaled: {time.UnscaledDeltaTime(Clock.Gameplay)}");
}
}
EditMode テストでは、Bootstrap は通常すでに実行されています — 起動フックはテストドメインでも発火します — ので、サービスをそのまま解決できます:
using CommonGameSystem.Core;
using NUnit.Framework;
public class BootstrapSmokeTests
{
[Test]
public void Bootstrap_RegistersCoreServices()
{
// Bootstrap.Run already fired for the test domain. Resolve and assert.
Assert.IsNotNull(ServiceLocator.Resolve<ILogger>());
Assert.IsNotNull(ServiceLocator.Resolve<IObjectPoolService>());
Assert.IsTrue(Bootstrap.HasRun);
}
}
API の全体像
解決すべきものはありません。Bootstrap は Unity の [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] フックによって自動的に発火します。あらゆるシーンの Awake より前、あなたのコードが Service Locator に触れるより前に実行されます。
namespace CommonGameSystem.Core
{
public static class Bootstrap
{
// Entry point — Unity calls this automatically (do NOT invoke directly).
public static void Run();
// Registers the settings-persistence backend. Public so automated
// tests can inject a stub; not part of normal use.
public static void RegisterConfigurationPersistence();
// Diagnostic-only (read-only — set internally). Editor-only:
// these two properties do not exist in player builds.
public static bool HasRun { get; }
public static int RunCount { get; }
}
}
| メンバー | 説明 |
|---|---|
Run() | 起動のエントリーポイント。Unity が Play セッションごとに一度、最初のシーンのロード前に呼び出します。自分でもう一度呼び出すと ServiceAlreadyRegisteredException がスローされます。 |
RegisterConfigurationPersistence() | Configuration サービスが設定の保存に使うストレージバックエンドを登録します: Save/Load サービスがアクティブならそれを、そうでなければ Unity の PlayerPrefs を使います。テストがフォールバックを検証できるようにするためだけに public になっています。通常の使用では呼び出しません。 |
HasRun | 起動が少なくとも一度完了していれば true。読み取り専用で、エディタ専用 — 参照は #if UNITY_EDITOR で囲むか、Editor/テストアセンブリの中に留めてください。 |
RunCount | 起動実行回数の累計(エディタで Domain Reload が無効の場合、Play セッションをまたいで増えていきます)。読み取り専用、エディタ専用。 |
登録順に見る 23 のサービス
Bootstrap は以下のサービスを、この順序で起動します。それぞれ ServiceLocator.Resolve<T>() で解決するインターフェースで、専用のリファレンスページがあります。
- ServiceLocator — 他のすべてのサービスが登録されるレジストリで、任意のサービスを取得するために呼び出す唯一のクラス。Service Locator を参照。
- ILogger — カテゴリ別フィルターを備えたカテゴリ化ロギング。Logger を参照。
- IObjectPoolService — プレハブのプーリング。Object Pool を参照。
- ITimeService — クロックごとの時間・ポーズ・スローモーション(Gameplay/UI/Background クロック)。Time を参照。
- IEventBus — システム間の型安全な publish/subscribe。Event Bus を参照。
- ISaveService — 安全なアトミック書き込みとスロットを備えた JSON セーブファイル。Save/Load を参照。
- IConfiguration — 変更イベント付きの型付き設定グループ。Configuration を参照。
- IInputService — 入力アクションマップのコンテキストとキーリバインド。Input を参照。
- IAudioService — AudioMixer を介した音楽・効果音・ボイス。Audio を参照。
- IPanelStack — ゲームパッドとキーボードのフォーカスに対応した UI パネルの push/pop。UI Framework を参照。
- ISceneService — ローディング画面・キャンセル対応・加算ロード/アンロードを備えた非同期シーンロード。Scene Flow を参照。
- ILocalizationService — キーから文字列への検索と実行時の言語切り替え。Localization を参照。
- IAchievementService — 自動アンロック付きのローカル統計と実績。Achievements を参照。
- IScheduler — After/Every/NextFrame タイマーとメインスレッド実行ディスパッチ。Scheduler を参照。
- ITweenService — 31 種類のイージングを備えたポーズ対応の値トゥイーン。Tween を参照。
- IAssetProvider — 参照カウント付きの Addressables ロード。Asset Provider を参照。
- IRandomService — 名前付きストリームを備えた、シード指定で再現可能な乱数。Random を参照。
- IStateMachineService — フラットな有限ステートマシンのファクトリ。FSM を参照。
- IPushdownStackService — スタック化されたゲームステートのスコープ(ゲームプレイの上にポーズメニュー、など)。Pushdown Stack を参照。
- ITweenSequenceService — 順次実行・並列実行のトゥイーンタイムライン。Tween Sequencing を参照。
- IAddressableSceneService — Addressables からロードする加算シーン。Addressable Scene を参照。
- IDeferredBus — イベントを今キューに積み、後でフラッシュ。Deferred Event Queue を参照。
- ICommandRegistry — ランタイムコマンドレジストリ(コンソール UI は自作します)。Command Registry を参照。
内部ヘルパーの登録
Bootstrap は、自動テストが差し替えられるように、いくつかの内部ヘルパーも登録します: 設定永続化バックエンド、3 つの組み込み設定バリデーター、入力キーマップソースです。ゲームコードがこれらを直接解決することはなく、23 サービスの数にも含まれていません。
挙動とエッジケース
-
一度だけ実行されます。 1 つの Play セッション内で
Bootstrap.Run()を 2 回呼ぶとServiceAlreadyRegisteredExceptionがスローされます。Unity のフックが Play 開始ごとにちょうど一度の発火を保証するため、自分で呼ぶ必要は一切ありません。 -
メインスレッド専用。 起動フックは Unity のメインスレッドで実行されます。Debug ビルドはこれをアサートし、違反は早期に検出されて Play が中断されます。
-
登録前のクリーンアップ。 サービスを登録する前に、Bootstrap は前回の Play セッションから残ったフレームワーク内部の GameObject を削除します。これが意味を持つのは、エディタで Domain Reload が無効なとき(Project Settings → Editor → "Enter Play Mode Settings")だけです。Domain Reload が有効なら、各 Play セッションはそもそもクリーンなヒエラルキーで始まります。フレームワークは内部のマーカーコンポーネントで自身の残存オブジェクトを見つけ、
Object.Destroyで破棄します — 即時ではなくフレーム終了時の破棄なので、PlayMode テストでは起動後にyield return nullして破棄を確定させてください。マーカーコンポーネントはフレームワーク内部用です。自分でアタッチしないでください。 -
Logger のウォームアップ。 起動中、Bootstrap はメインスレッドで Logger を一度呼び出します。この呼び出しが static な
Loggerヘルパーを準備し、以降のワーカースレッドからの呼び出し(たとえばセーブファイルの I/O)を安全にします。 -
起動の失敗は Play を停止します。 シーケンスの後半で生成されるサービスは、依存関係をコンストラクター経由で受け取ります。コンストラクターがスローすると例外は伝播し、Play は即座に中断されます — 問題は数分後ではなく、起動時に表面化します。
-
エディタのシャットダウンフック。 エディタでのみ、Bootstrap は Play モードの終了を監視し、破棄可能なすべてのサービスを登録の逆順で破棄します。プレイヤービルドにこのフックは含まれません — 通常のプロセス終了処理に任せます。
-
Bootstrap 自体は差し替えできません — 他のすべてを起動するコードそのものだからです。ただし、登録される各サービスは差し替え可能で、どのサービスにも 1 行でオフにできる Null(no-op)実装が付属しています:
// Example: silence all diagnostics ServiceLocator.Replace<ILogger>(new NullLogger()); // Example: disable audio entirely ServiceLocator.Replace<IAudioService>(new NullAudio()); // Example: stub the scene service for testing ServiceLocator.Replace<ISceneService>(new NullSceneService());Logger には 1 つ注意点があります: static な
Loggerヘルパーは起動時にバックエンドをキャッシュするため、セッション途中で差し替えてもリターゲットされません。実行時にロギングをミュートするには、代わりにLogger.MinimumLevel = LogLevel.Offを設定してください — 詳細は Logger を参照。
関連ページ
- Service Locator — 任意のサービスの取得方法
- Logger — 診断機能と、セッション途中のバックエンド差し替えに注意が必要な理由
- はじめに — インストール、最初のシーン、起動ログ行の確認
- マニュアル: 手に入るもの — パッケージ構成と全機能ツアー
- マニュアル: トラブルシューティング — 起動ログ行が表示されないときの確認事項