i-school - 2DタイルマップRPG 手順13
 前回実装を行ったイベント用のデータベースである EventDataSO スクリプタブル・オブジェクトをゲーム内で活用する処理について実装を行います。
2回に分けて実装してきます。

<実装動画>
動画ファイルへのリンク


手順13 −イベント用のデータベースの登録−
23.DataBaseManager スクリプトを作成して、スクリプタブル・オブジェクトを管理・運用できる状態にする


 新しい学習内容は、以下の通りです。

 ・シングルトンデザインパターンによるクラスの作成
 ・スクリプタブル・オブジェクトをゲーム内で利用できるようにする方法



23.DataBaseManager スクリプトを作成して、スクリプタブル・オブジェクトを管理・運用できる状態にする

1.設計


 この手順は、スクリプタブル・オブジェクトをゲーム内で利用するための処理を作成します。

 作成したスクリプタブル・オブジェクトをゲーム内で利用するためには、他のスクリプトやコンポーネントと同じように
いずれかのスクリプト内においてSerializeField属性 や public 修飾子で型の宣言を行います。
そして用意した変数内に、インスペクターよりスクリプタブル・オブジェクトをアサインすることで利用可能になります。

 今後もスクリプタブル・オブジェクトを管理することを前提とし、スクリプタブル・オブジェクト関連の情報を管理するためのスクリプトとして
DataBaseManager スクリプトを作成し、その中で型と変数の宣言を行うようにします。

 スクリプタブル・オブジェクトはデータベースという特性上、色々なスクリプトから参照されることを見越して作成しておくと利便性が増します。
そうなった場合、各スクリプトに毎回 DataBaseManager スクリプトの情報を宣言して利用できるようにしてもよいのですが、
この設計方法ですと、新しいスクリプトを作成するたびに、DataBaseManager スクリプトの情報を都度用意する必要が発生してしまい、管理が大変になります。

 C# にはシングルトンデザインパターンという便利な機能がありますので、こちらを利用して、DataBaseManager スクリプトの作成を行います。



 シングルトンデザインパターンという方式で作成した DataBaseManager クラスを用意して、その中に上記の情報を作成します
シングルトンで作成した DataBaseManager クラスは、変数への代入処理を行うことなく外部のスクリプトで利用できるクラスになります。

 処理の流れは次のように設計しています。

<処理の流れ>
 1.DataBaseManager クラス内に、スクリプタブル・オブジェクトと、そのスクリプタブル・オブジェクトを利用できるメソッドを準備しておく
 2.NCP がゲームスタート時に DataBaseManager クラスに用意しておいたデータベースから会話イベントを取得するメソッドを実行し、必要な会話イベントを取得する
 3.プレイヤーキャラが NPC に会話イベントを発生させると、このデータベースから取得している会話イベントの情報を利用して表示を行う

 これが DataBaseManager クラスの役割になります。
各クラスごとの役割を明確に分担しておくことで設計を作りやすくし、管理もしやすくなりますので、是非心がけてください。
 

2.<シングルトンデザインパターン>


 シングルトンとは、数多くあるデザインパターンの1つです。
そのクラスのインスタンスが必ず1つであることを保証するデザインパターンのことを言います。

 DataBaseManager クラスでは、このシングルトンを採用しています。
つまり、ゲーム中を通じて、この DataBaseManager クラスが1つしか存在できないようになります。
実装例は複数ありますが、一番読みやすい方式で記述しています。



<シングルトンデザインパターンのクラスの作成方法>
    public static DataBaseManager instance;

    private void Awake() {
        if (instance == null) {
            instance = this;
            DontDestroyOnLoad(gameObject);
        } else {
            Destroy(gameObject);
        }
    }



 ポイントは、自分自身の DataBaseManager 型を static 修飾子付きの instance 変数として宣言していることです。
この instance 変数が DataBaseManager クラス自身が代入された情報として利用することになります。

 Awake メソッドを利用して、instance 変数が null (空っぽ) である場合には、DataBaseManager クラス(this)を代入します。
次の DontDestroyOnLoad メソッドは Unity が用意しているメソッドで、引数に指定されたゲームオブジェクトはシーン遷移をしても破壊されてないゲームオブジェクトになります。
この DontDestroyOnLoad メソッドはシングルトンデザインパターンにする際に一緒に用いられることが多いです。

 そして instance 変数が null ではない場合、つまり、2つ目以降の複数の DataBaseManager クラスが存在する場合には、その DataBaseManager クラスのゲームオブジェクトを Destroy します。
この手順により、DataBaseManager クラスがアタッチされているゲームオブジェクトが常にヒエラルキー上に1つしか存在しない状態を作り出しています

 このシングルトンによってインスタンスが1つか生成されないことが保証されますので、
逆説的に考えると、この DataBaseManager クラスへの参照は、いずれのクラスからであっても変数を介さずに参照を行えるようになります。



 例えば、NonPlayerCharacter というクラスがあり、その NonPlayerCharacter クラスを持つゲームオブジェクトが5つあった場合、
どの」NonPlayerCharacter クラスであるかを確定できないと、対象となる NonPlayerCharacter クラスへは参照できません。
そのため、NonPlayerCharacter 型の変数を用意して、その変数へ参照したい NonPlayerCharacter クラスを代入することによって、
はじめて NonPlayerCharacter クラスの情報を扱うことができるようになります。これが情報を扱う際の基本的な処理になります。

 ですがシングルトンである DataBaseManager クラスの場合には、このインスタンスは常に1つしかないことが保証されていますので、「どの」という指定の部分が不要になります。
よって変数への代入が不要になります。
DataBaseManager という指定はすなわち、自動的にただ1つの DataBaseManager クラスの参照が行われることになるためです。


3.DataBaseManager ゲームオブジェクトを作成する


 最初に、DataBaseManager スクリプトをアタッチするゲームオブジェクトを作成します。

 ヒエラルキーの空いている場所で右クリックをしてメニューを開き、Create Empty を選択します。
新しいゲームオブジェクトが作成されますので、名前を DataBaseManager に変更してください。

 Transform コンポーネントを確認して、Position の値を (0, 0, 0) に戻してください。最初からその状態なら変更は不要です。


ヒエラルキー画像



DataBaseManager ゲームオブジェクト インスペクター画像



 以上でこのゲームオブジェクトは完成です。


4.DataBaseManager スクリプトを作成する


 設計とシングルトンデザインパターンの書式を参考して、DataBaseManager スクリプトを作成します。
スクリプタブル・オブジェクトを登録して管理するための変数を EventDataSO 型で宣言しておきます。
スクリプタブル・オブジェクトと同じ型にすることで代入が可能になります。

 このとき、SerializeField 属性付きで宣言しておくことによって、インスペクターよりスクリプタブル・オブジェクトの代入が可能になります。



 メソッドは1つ用意します。

 用意するメソッドは戻り値を持つメソッドです。このメソッドを外部のスクリプトから参照することにより、
引数で受け取った情報を検索対象として、EventData 型の情報を抽出して取得することができるようにします。いわゆる、ゲッターメソッドになります。

 このメソッドは外部のスクリプトから呼び出されることで利用することを前提にしています。
このメソッドを実行する際に、引数として検索したい情報を渡して命令を実行することにより、
EventDataSO スクリプタブル・オブジェクトに登録されているデータ内を検索し、取得したい EventData を1つ探して取得を行うことができるようになります。


DataBaseManager.cs


 スクリプトを記述したらセーブします。


5.DataBaseManager ゲームオブジェクトに DataBaseManager スクリプトをアタッチしてスクリプタブル・オブジェクトを登録する


 ヒエラルキーにある DataBaseManager ゲームオブジェクトに、作成した DataBaseManager スクリプトをドラッグアンドドロップしてアタッチします。
アタッチしたら、必ず対象のゲームオブジェクトのインスペクターを確認して、アタッチ漏れがないかを確認します


DataBaseManager ゲームオブジェクト インスペクター画像



 EvenDataSO 変数の部分に、Datas フォルダ内にある EvenDataSO スクリプタブル・オブジェクトをドラッグアンドドロップしてアサインしてください。
これでスクリプタブル・オブジェクトを変数の値として代入することが出来ます。(スクリプト・ファイルの方ではありません)


DataBaseManager ゲームオブジェクト アサイン後のインスペクター画像



 以上で設定は完了です。



 以上でこの手順は終了です。

 次は 手順14 ーイベント用のデータベースの利用ー です。