i-school - テキストアドベンチャー 手順13
 以下の内容で実装していきます。

30.条件付きの分岐機能(今までに選択していた選択肢に応じた分岐の生成)を実装する



 新しく学習する内容です。

 ・Linqを利用した配列のContaisメソッド
 ・for文のcontinueキーワード



30.条件付きの分岐機能(今までに選択していた選択肢に応じた分岐の生成)を実装する


 プレイヤーがゲーム内で選択していた分岐の内容を条件に、特定の分岐を通過していないと表示されない分岐を作成する機能を実装します。

 例えば、3番の分岐ルートを選択して通過していない場合には、その先にある7番の分岐が表示されない、という条件を付けた分岐を作る機能です。


設計


 プレイヤーがどういった選択肢でゲームを進行しているのかを把握し、それに合わせて条件つきの分岐を判定していくようにします。

 プレイヤーが選択した分岐の選択肢については、GameDataスクリプトに新しくList<int>型の変数を用意し、
そちらに、選択を行うたびに順次、選択した分岐の番号を追加していくようにします。

 例えば、最初の分岐で2番の番号を持つ分岐を選択した場合には、このListに 2 という番号を登録しておきます。
これを選択肢を選ぶたびに追加していきます。そうすることで、プレイヤーが選択してきたすべての選択肢を確認することが出来ます。

 この情報を条件の要素として利用し、このListに含まれている番号を条件を満たしている番号として使うようにします。


 そのためにまず、Excelファイルでの分岐番号の持たせ方を変更します。
いままでは分岐の数に合わせてカンマ区切りで番号のみを登録していましたが、条件付きの分岐番号の場合には、半角スラッシュ / を使って
1つの分岐番号に2つの情報を持たせるようにします。最初の番号が条件となる分岐の番号、2番目の番号が今までと同じ分岐の番号です。

 ゲーム内では、1番目の番号を分岐の条件番号として判定し、その番号がGameDataのListに登録されている場合に限り、2番目の番号を分岐用のボタンとして生成します。

 "4/6, 8, 2"

 条件を持たない分岐番号は、今までと同じように分岐する番号のみを書きます。

 上記の例では、分岐は3つ存在し、その内の最初の分岐には条件があり、残る2つは条件なしで生成される分岐になります。
最初の分岐番号は、 4 という番号の分岐を通過している(GameDataのListに登録がある)場合に限り、 6 という分岐を生成するようになります。


実装手順


 以下の手順で実装を行います。

 1.Excelファイルを修正して、分岐の番号の登録方法を変更する
 2.SenarioMasterDataスクリプトを修正して、条件付きの分岐情報を登録できるようにする
 3.GameDataスクリプトを修正して、プレイヤーが選択した分岐の番号を登録できるようにする
 4.GameDirectorスクリプトを修正して、条件付きの分岐を判定する処理を追加する
 5.TextMessageViewewスクリプトを修正して、条件付きの分岐情報を管理する処理を追加する


1.Excelファイルを修正して、分岐の番号の登録方法を変更する


 条件をつけたい分岐番号の情報を変更します。

 "1/4" のように、最初に条件となる分岐の番号 / 生成される分岐の番号 の書式で記述してください。
なおプログラム上、条件付きの分岐が先頭にくるように記述してください。

 複数条件付きの分岐がある場合には  "1/4, 2/6, 3" のように、条件のないものを最後に記述するようにしてください。


サンプル Jsonファイル

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



2.SenarioMasterDataスクリプトを修正して、条件付きの分岐情報を登録できるようにする


 【1】で作成したExcelデータをゲーム内に読み込めるように、スクリプトを修正します。

Excel => Jsonからスクリプタブル・オブジェクトを作成している場合


SenarioMasterData.cs

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



Excel ImporterでExcelファイルから直接スクリプタブル・オブジェクトを作成している場合


Scenario.cs

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



3.GameDataスクリプトを修正して、プレイヤーが選択した分岐の番号を登録できるようにする


 条件付きの分岐情報と照合するために、プレイヤーが選択した分岐情報をGameDataに登録出来るようにします。
また、ExcelやJsonのファイルの読み込みを行う際に、条件付きの分岐情報を先ほど変更したScenerioDataList(Sceneario)に登録できるように、読み込み方法を修正します。


GameData.cs

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



<Linqを利用した配列のContaisメソッド>


 Containsメソッドはbool型の戻り値を持つ、StringクラスやListクラスの持つメソッドの1つです。どちらも使い方は同じです。
Contains(引数)で使用し、引数として指定した値がStringクラスやListクラス内の要素に含まれているかを判定します。
含まれている場合には true、含まれていない場合には false を戻してくれるメソッドです。
 Containsの引数はジェネリック型です。そのためその都度、定義している型に応じて指定する要素を変更できます。

 配列にはContainsメソッドはありませんが、Linqの持つContainsメソッドを利用することで配列に対してもContainsメソッドを利用することが出来ます。

 using System.Linq;

  if (tempBranchNos[x].Contains("/")) {

 こちらでは引数として文字列の / を指定しています。理由はString型の配列であるため、文字列の中を検索したいためです。
もしも tempBranchNos[x] 変数内に / が含まれている場合、true が戻ってくるため、if文の条件を満たすことになります。
 
参考サイト
SamuraiBlog
【C#入門】Containsで値が含まれるか調べる方法(文字列/配列/List)
https://www.sejuku.net/blog/41745


4.GameDirectorスクリプトを修正して、条件付きの分岐を判定する処理を追加する


 CreateBranchSelectButtonメソッドの引数と処理の内容を修正します。
分岐ボタンを生成する前に条件を持つ分岐かどうかを確認し、条件を持つ場合にはそれを満たしている場合のみ、分岐ボタンを生成するように制御処理を追加します。

 該当のメソッドのみを記載します。


GameDirector.cs

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



<for文のcontinueキーワード>


 ループの処理を終了(スキップ)し、ループの先頭に戻る処理です。もしも処理の途中で continue が実行された場合、この処理以降の処理は行われずに、ループの先頭に戻ります。

  // メッセージの数分の分岐ボタンの生成
  for (int i = 0; i < branchMessages.Length; i++) {

  ////* ここから追加 *////

      // 生成する分岐が、条件のある分岐か確認
      if (i < conditionalBranchNo.Count) {
          // 分岐の条件の番号を通過しているか確認。通過していなければ分岐を表示しない
          if (!GameData.instance.chooseBranchList.Contains(conditionalBranchNo[i])) {

              continue;    <= 処理をスキップし、for文の先頭に戻る
          }
      }

 この分岐の場合、if (!GameData.instance.chooseBranchList.Contains(conditionalBranchNo[i])) { の条件を満たした場合に continue が実行されます。
その場合、この処理以降にある分岐ボタンの生成処理が行われずに、for文の先頭に戻り、次のループ処理が開始されます。


5.TextMessageViewewスクリプトを修正して、条件付きの分岐情報を管理する処理を追加する


 宣言フィールドに conditionalBranchNo 変数を追加し、条件付きの分岐の情報を管理できるようにします。
SetUpScenarioDataメソッドの処理を追加し、作成した conditionalBranchNo 変数に条件付きの分岐情報を代入します。

また分岐ボタンを生成するメソッドの呼び出しの引数に第3引数を追加します。

TextMessageViewew.cs

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



ゲームを実行して動作を確認する


 以上で手順は終了です。ゲームを実行して動作を確認します。

 GameDataのListの値を見て、条件のある分岐ボタンが生成される/されない状態を両方確認してください。


 おつかれさまでした。