3rd term 1st week - dsuz/csharp GitHub Wiki
今回のテーマ
- シングルトン パターン
準備1
以下のアセットをプロジェクトにインポートします
シーンでは Tilemap を使っています。また、FieldLeft, FieldRight シーンは実行中に互いに切り替わるので、両シーンを Scenes In Build に登録する必要があります。
サンプル シーンの特徴
サンプルシーン FieldLeft, FieldRight は以下の特徴があります。
- FieldLeft/FieldRight のどちらのシーンから実行を開始してもよい
- FieldLeft の右端に移動すると、FieldRight に切り替わる
- FieldRight の左端に移動すると、FieldLeft に切り替わる
- SingletonSystem コンポーネントの Bullets In Scene を変更すると、連射できる弾数が増える
- SingletonSystem コンポーネントは FieldLeft, FieldRight の両シーンに存在するが、実行を開始したシーンにあるインスタンスが(シーンが切り替わっても)維持される
最後の特徴はシングルトン パターンによって実現されている。この仕様により、「各シーンに独自の(Bullets In Scene の)設定をすることができる。これは開始するシーンによって異なる設定が許されるということで、開発中に非常に有効である。
シングルトンとは
シングルトンとは「そのクラスのインスタンスが一つしかない」ことを保証する作り方(パターン)である。サンプルでは SingletonSystem クラス(コンポーネント)がシングルトン パターンで作られているが、これは「既にそのクラスのインスタンスが存在する場合はオブジェクトごと破棄する」ことで「そのクラスのインスタンスが(シーン内に)一つしかない」状態を維持している。
この方法は Unity においては「シングルトン パターンで作ったコンポーネントを各シーンにあらかじめ置いておくことができる」というメリットがある。これにより、各シーンから実行を開始できる(遷移前のシーンから開始する必要がない)、また該当のコンポーネントの値を設定可能にしておくことで、各シーンから開始した時の設定をあらかじめセットしておくことができる。これは開発やデバッグなどに大変都合がよい。
参考資料
- 独習 C# 7.5.3 - シングルトン パターン
シングルトン パターンの実装方法
上に述べた用に、サンプルでは「既にそのクラスのインスタンスが存在する場合はオブジェクトごと破棄する」ことでシングルトンを実現しているが、シングルトン パターンそれ自体については作り方は一つではない。様々なやり方がある。
- MonoBehaviour を使わないパターン
- 参照: Hierarchyを汚さないポータブルなUnity向けSingletonの実装の話
- ただし、この方法ではクラスはコンポーネントではなく GameObject に追加できないため、「Inspector から値を指定できない」という問題がある
- ジェネリックを利用したシングルトンのベースクラスを継承して作る
- 以下のように様々なベースクラスが公開されている(新しい順)
チャレンジ
上記の「ジェネリックを利用したシングルトンのベースクラスを継承して作る」で紹介したシングルトンのベースクラスを使って、自分のプロジェクトのゲーム管理クラスをシングルトン化したり、サンプルの SingletonSystem コンポーネントを「シングルトンのベースクラスを継承してシングルトン パターンを実装する」ように修正してみるとよいでしょう。
なお、このチャレンジは課題の評価には影響しません。