i-school - 強制横スクロールゲーム 手順24
 何回も繰り返してゲームを遊べるようにするために、ゲームのサイクル化を行っていきます。

 この手順では空中床を一定回数生成したら、ゴール地点を生成する処理を実装していきます。


<実装動画 条件を満たしたらゴール地点を生成する>
https://gyazo.com/18abb10cf2714645b98179114f2ef531


手順24 ークリア条件とゴール地点の自動生成処理の実装ー
42.床の生成数をカウントして、規定数に達したらゴール地点を生成する



 新しく学習する内容は以下になります。

・プロパティの設定
・プロパティの利用 −private 修飾子の値を外部クラスで参照(ゲット)する−



42.床の生成数をカウントして、規定数に達したらゴール地点を生成する

1.設計


 特定の状態においてある処理を行いたい、という制御を考えた場合、その特定の状態をどのようにして作るかが重要になります。
今回のゴール地点を生成するための制御処理も同じで、生成を行うためには、特定の状態を満たす条件を設定する必要があります。

 どのような条件にしてもよいのですが、今回は、空中床を生成した回数をカウントし、その生成回数が一定値に達したら、
ゴール地点を生成するように条件を設定して制御を行っておきます。
 
 もちろん他の条件でも生成することは可能ですので、自分でも設計を考えてロジックを組んで実装をしてみましょう。
どのような条件とするか、どの条件を判定するにはどういった情報(変数など)が必要か、という風に考えていくとよいと思います。

 空中床を生成した回数のカウントや、一定回数の設定を行うために、新しく GameDirector(あるいは、GameManager) スクリプトを作成して管理を行うようにします。


2.GameDirector スクリプトを作成する


 このスクリプトによって、ゴール地点が生成されるための制御処理を行っています。
一体どのようにして処理が動いているか、また、どのような順番で処理が行われることによってゴール地点が生成されるのか、
一連の処理の流れを自分で書き出してみましょう。

 用意している変数も同様です。なぜ必要なのか、どういった部分に利用されているのかを確認し、処理を追いかけてみましょう。


GameDirector.cs

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



 TODO の部分には後程、処理を追加します。このように処理が追加される場所を残しておいたり、Debug.Logを入れておくと、処理の書き洩らしを減らすことが出来ます。


3.<プロパティの設定>


 プロパティとは、クラス外部から見るとメンバー変数のように振る舞い、 クラス内部から見るとメソッドのように振る舞う機能です。
そのため、実装状態(private修飾子のまま)を変更することなく、外部クラスへの参照・変更を行える機能であるため、扱いを覚えておくと非常に便利です。


プロパティ
    // 生成回数
    private int generateCount;

    // generateCount 変数用のプロパティ
    public int GenerateCount
    {
        set {
            generateCount = value;

            Debug.Log("生成数 / クリア目標数 : " + generateCount + " / " + clearCount);

            if (generateCount >= clearCount) {
                // ゴール地点を生成
                GenerateGoal();

                // ゲーム終了
                GameUp();
            }
        }
        get {
            return generateCount;
        }
    }

 今回は、private で宣言している generateCount 変数をプロパティを利用することによって、外部クラスから参照出来るようにしています。

 private 修飾子にて宣言フィールドで宣言した変数については、外部のクラスからは参照・変更を行うことが出来ません。
このとき、どうしても参照を行いたい場合には、変数の修飾子を public 修飾子に変更して対応するのではなく
プロパティの持つ get キーワードを利用して、戻り値を利用して private 修飾子の変数を外部クラスに参照させることが出来ます。

 この設計により、public ではない変数を外部クラスで利用できるようにします。
外部からプロパティを呼び出して戻り値を参照する処理のことをゲッター(getter)と呼びます。

 同様に、private 修飾子の値を外部クラスより変更したい場合には、同じプロパティをを仲介する手法を使って書き換える処理を実装出来ます。
こちらの処理はセッター(setter)と呼びます。


 get、set キーワードはどちらか片方だけでも記述できます。また今回のように、プロパティ内部に条件式を用意して、その結果に合わせて処理を変更する記述も出来ます。

 実際の利用方法については次の手順で紹介します。


参考サイト
未確認飛行 C 様
プロパティ
https://ufcpp.net/study/csharp/oo_property.html

FEnetインフラ様 テックブログ
C#のプロパティを使いこなそう!さまざまな実装方法を紹介
https://www.fenet.jp/infla/column/technology/c%E3%...


4.GameManager ゲームオブジェクトに GameDirector スクリプトをアタッチして設定を行う


 ヒエラルキーにある GameManager ゲームオブジェクトに、作成した GameDirector スクリプトをドラッグアンドドロップしてアタッチします。
GameManager ゲームオブジェクトを選択して、インスペクターを確認してください。GameDirector スクリプトにアサイン情報が表示されますので、順番に設定します。


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



 各変数にアサインする情報については、スクリプトの変数のコメントを参照してください。
clearCount の値はデバッグがありますので、現時点では 2 - 3 に設定しておいて、処理が問題なくなったら適宜な値に変更してください。


<手順動画 アサイン>
https://gyazo.com/aa26ec552046717e6ded715cdbb6728f


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



5.FloorGenerator スクリプトを修正する


 空中床を自動生成するスクリプトを修正して、空中床を生成した回数を GameDirector スクリプトの GenerateCount プロパティを通じて加算する処理を追加します。
そのために、GameDirector スクリプトを取得するためのメソッドも追加しています。


FloorGenerator.cs

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



6.<プロパティの利用 −private 修飾子の値を外部クラスで参照(ゲット)する−>


 GameDirector スクリプトに用意した generateCount 変数を参照するためのプロパティ(GenerateCount)を今回の処理では実装しています。


    // 生成数をカウントアップ
    gameDirector.GenerateCount++;

 プロパティは public 修飾子ですので「クラスの代入されてる変数名.プロパティ名」と記述することで参照することが出来ます。(gameDirector.GenerateCount)
この機能によって、private 修飾子である generateCount 変数の値を外部のクラスで参照できるようになっています。

 プロパティはメソッドと同じように、名前の頭文字を大文字にしておくと、このように外部クラスで参照を記述する際にもプロパティであることと分かりやすくなります。


7.GameDirector スクリプトの SetUpFloorGenerators メソッド内のコメントアウトを解除する


GameDirector.cs
    private void SetUpFloorGenerators() {
        for (int i = 0; i < floorGenerators.Length; i++) {
            // FloorGeneratorの準備・初期設定を行う
            floorGenerators[i].SetUpGenerator(this);           // <= コメントアウトを解除
        }
    }


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


 ゲームを実行して、空中床が生成されるたびに、GameDirector スクリプトの generateCount 変数が加算されるかを確認します。
generateCount 変数は private 修飾子ですので、Debug.Logに加算回数を表示するように制御しています。

 またこの回数が clearCount 変数と同じ値になったときに、ゴール地点のゲームオブジェクトが生成されれば成功です。


<実行動画 空中床が生成されるたびに、GameDirector スクリプトの generateCount 変数が加算される(Console で確認)>
https://gyazo.com/e7a02a0a12cbe1bb3e3e2e90e729bb3c


<実行動画 generateCount 変数の値が clearCount 変数と同じ値になったときに、ゴール地点のゲームオブジェクトが生成される>
https://gyazo.com/7aa75eba369542f78d9d81db273b4369


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

 ただし、いまのままですと、何回もゴールが生成されてしまうようになっていますので、次の手順はその制御を行い、ゴール地点の生成を1回だけにします。

 次は 手順25 ー自動生成の制御処理の実装ー です。