i-school - 3Dレールガンシューティング 発展3
 現在は RailPathData ゲームオブジェクトは1つであるため、移動経路の情報が1つしかありません。
これを複数作成して管理させることを目的とした StagePathData クラスと BranchData クラスを作成します。
さらに、その StagePathData クラスをまとめておくことで、1つ分のステージのデータとして活用していく設計と実装を行います。



発展3 ーステージデータの作成ー

<学習内容>
 ・クラス内に別のクラスを作成する(入れ子クラス)機能の復習
 ・List.Find メソッドー



設計


 次のような構成でクラスの設計を行います。

 StagePathData クラスが複数の BranchData クラスを管理します。
この BranchData クラスは1つ分の分岐になります。

 BranchData クラス内には複数の RailPathData クラスを管理し、その分岐内の経路情報を管理します。

 StagePathData クラス(ステージ1つ分)
        |
        | --------BranchData クラス
        |               |
        |               | --------RailPathData クラス
        |             | --------RailPathData クラス
        |               | --------RailPathData クラス
        |               | --------任意の数だけ RailPathData クラス を管理する
        |
        |
        |-------- BranchData クラス
        |               |
        |               |-------- RailPathData クラス
        |              |-------- RailPathData クラス
        |               |-------- RailPathData クラス 
        |               |-------- 任意の数だけ RailPathData クラス を管理する
        |               
        |    
        |-------- BranchData クラス
        |               |
        |               |-------- RailPathData クラス
        |              |-------- RailPathData クラス
        |               |-------- RailPathData クラス 
        |               |-------- 任意の数だけ RailPathData クラス を管理する
        |    
        |-------- 任意の数だけ BranchData クラスを管理する        

 このイメージを忘れずに、どういった構造になっているのかを念頭に置きながら実装を行っていきます。


新しい RailPathData ゲームオブジェクトを作成する


 1つのステージは、複数の BranchData クラスによって分岐が発生し、その BranchData クラスの中に含まれる RailPathData によって経路が設定される設計になっています。
そのため、現在の RailPathData ゲームオブジェクトを参考にしながら、異なる経路を持つ RailPathData ゲームオブジェクトを作成してください。

 最低でも2つ以上ないと、先々の分岐の処理を作成することが出来ません。
作成したら、それらをプレファブにして、ヒエラルキーからは削除しておいてください。


BranchDirectionType スクリプトを作成する


 分岐先の種類について、事前に enum を作成して種類を登録しておきます。


BranchDirectionType.cs

<= クリックしたら開きます。



スクリプトを作成したらセーブを行います。


StagePathDataSO スクリプトを作成する


 複数の RailPathData を管理し、それをまとめて1つのステージとして管理するために、新しくスクリプタブル・オブジェクト用のクラスと
それを構成するための BranchData クラスを作成します。

 スクリプタブル・オブジェクト用のクラスは、1つのクラス内に入れ子クラスを作り、1つのスクリプト内にまとめて宣言する方法と、
各クラスごとにスクリプトを1つずつ作成する方法があります。

 今回は1つのスクリプト内に入れ子クラスを2つ作成してまとめて宣言し、合計で3つのクラスをまとめています。


StagePathDataSO.cs


 スクリプトを作成したらセーブします。


StagePathDataSO スクリプタブル・オブジェクトを作成する


 Datas フォルダ内で右クリックをしてメニューを開き、Create => Create StagePathDataSO を選択してスクリプタブル・オブジェクトを作成します。

 インスペクターを確認し、Size が 0 になっていますので、こちらを 2 以上に設定し、先ほど作成した RailPathData ゲームオブジェクトのプレファブをアサインしてください。
BranchDirectionType には分岐する方向を設定することになりますが、現在は No Branch を選択しておいてください。


インスペクター画像 参考例


 以上で設定は完了です。


DataBaseManager スクリプトを修正する


 新しく作成した StagePathDataSO スクリプタブル・オブジェクトをゲーム内で利用できるように
DataBaseManager に変数を追加して管理を行います。

 合わせて、StagePathDataSO スクリプタブル・オブジェクト内の情報を扱いやすくするため、
指定した情報を抽出して提供できるように、戻り値のあるゲッターメソッドを5つ作成しておきます。

 各メソッド内では、StagePathDataSO スクリプタブル・オブジェクトに対しての抽出処理などがメソッド単位でまとめられています。
また、その中では System.Linq ライブラリを利用している部分があるため、using に宣言の追加を行っています。
利用している Select メソッドと ToArray メソッドについては、手順8にて、すでに学習済です。復習として、しっかりと理解を深めてください。

 List 内部情報の参照の仕方や抽出の仕方の多くは、他の List でも応用が利く内容になっています。
そのため処理の内容をしっかりと理解してから学習を進めていくことを強くお勧めします。
List は作ったり、値を追加しているだけでは活用出来ません。List の内部情報に対しての抽出処理や検索処理といったアクセスの方法を覚えてはじめて役立ちます。


DataBaseManager.cs

<= クリックすると開きます


 スクリプトを修正したらセーブします。


<List.Findメソッド>


 Listには Find というメソッドがあります。
List 内の要素を先頭から検索して、指定した条件に合致した最初の要素1つを取り出して戻り値として返してくれる処理です。
Find メソッドは foreach 文で記述する内容と同じ処理を1行で処理できます。

Find の場合
public RailPathData GetRailPathDatasFromBranchNo(int nextStagePathDataNo, BranchDirectionType searchBranchDirectionType) {
    return stagePathDataSO.stagePathDatasList[nextStagePathDataNo].branchDatasList.Find(x => x.branchDirectionType == searchBranchDirectionType).railPathData;
}

foreach で同じ処理を書いた場合
  foreach (BranchData data in stagePathDataSO.stagePathDatasList[nextStagePathDataNo].branchDatasList) {
        if (data.branchDirectionType == searchBranchDirectionType) {
            return data.railPathData;
        }
    }

 この2つの処理は同じ内容になります。
最初に合致した値が対象になりますので、まとめて複数取得したい場合や、合致する条件を満たす要素が複数ある場合には、この処理だけでは実装できません。


参考サイト
Samurai Blog様
【C#入門】Listの要素を検索するFindの使い方(FindAll/FindIndex)
https://www.sejuku.net/blog/45252


DataBaseManager ゲームオブジェクトの設定を行う


 DataBaseManager スクリプトを修正し、新しい変数を追加したのでインスペクターから確認して設定を行います。
対象の変数に Datas フォルダ内にある StagePathDataSO スクリプタブル・オブジェクトをドラッグアンドドロップしてアサインします。


インスペクター画像


 以上で設定は完了です。



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

 ここまでの手順でステージ用の情報を管理することができることになりました。
次の手順ではこのステージの情報を自動的に参照して読み込んで、経路の情報を設定する機能の実装を行います。

 今までよりも更に難しい処理が増えていきますので、しっかりと処理の内容を理解できるよう、
1回スクリプトを書いて終わりではなく、復習を行いながら処理を読み解いていくことが求められます。


 => 次は 発展4 ーステージ内の移動経路情報の自動切り替え機能ー です。