i-school - 強制横スクロールゲーム 手順13
 以下の内容で順番に実装を進めていきます。

手順13 −スタート地点の移動処理−
21.ゲームがスタートしたら、スタート地点の地面のゲームオブジェクトが移動を開始するように制御を行う
22.ゲームスタートではなく、キャラがバルーンを生成したら、スタート地点の地面のゲームオブジェクトが移動を開始するようにする制御を行う


新しく学習する内容


・スクリプトを通じて、他のゲームオブジェクトにアタッチされているコンポーネントやスクリプトを操作する


21.ゲームがスタートしたら、スタート地点の地面のゲームオブジェクトが移動を開始するように制御を行う

設計


 いままでに実装してきた手順によって、まだまだ内容的にはこれからですが、
背景のスクロールと空中床の移動により強制スクロールのゲームの体を成してきました。

 まずは現在の状態を確認しましょう。


<実行動画>
https://gyazo.com/49740e96f39997615dea921c67d714f1


 空中床は画面の左端に移動をしていますが、スタート地点の地面役のゲーオブジェクトはずっとそのまま残っています。
この手順では、このスタート地点の地面用のゲームオブジェクトも画面の左端へと移動する処理を実装していきます。

 2段階のステップで処理を実装していきます。
まずは最初に、ゲームのスタートと同時にスタート地点のゲームオブジェクトを移動させる処理を実装します。
その後、特定の条件を満たすことによって、初めてスタート地点のゲームオブジェクトが移動するようになる処理を実装します。

 特に2つ目の処理の実装が重要な学習要素になります。


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


 先ほどの手順で作成した、MoveObject スクリプトを Ground_Start ゲームオブジェクトにアタッチして、空中床のゲーオブジェクトと同じように移動をさせてみます。
MoveSpeed の値を 0.005 に設定します。


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



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


 ゲームを実行して処理に問題がないかを確認していきます。

 ゲームのスタートに合わせて、スタート地点のゲームオブジェクトが画面の左側に向かって移動を始め、一定の地点まで移動後に自動的に破棄されれば成功です。

<実行動画>
https://gyazo.com/38e147399f82679be1205c0db1953365


22.ゲームスタートではなく、キャラがバルーンを生成したら、スタート地点の地面のゲームオブジェクトが移動を開始するようにする制御を行う

設計


 ここでは、ゲームオブジェクトの制御を、別のスクリプトを通じて操作する方法を学習します。

 ゲームのスタートに合わせて移動をすることは確認できましたので、次は、特定の条件を満たすことによって、スタート地点のゲームオブジェクトが移動を行うという制御を追加します。
今回の条件には「キャラが初めてバルーンを生成したら」という条件を設定します。この条件を満たすことで初めて、スタート地点のゲームオブジェクトが動きだ巣ようにします。

 スタート地点のゲームオブジェクトには、MoveObject スクリプトがアタッチされており、このスクリプトの持つ MoveSpeed 変数に 0 以上の値を設定することで
ゲームオブジェクトを移動させる処理が実行されます。

 まずは最初に、この Ground_Start ゲームオブジェクトの MoveObject スクリプトをインスペクターで確認し、MoveSpeed の値を 0 に変更します。
こうすることにより、このゲームオブジェクトはゲームが実行されても移動を開始することはなくなりました。(ゲームを実行して確認しておきましょう)

 この MoveSpeed の値がゲーム内において 0 以上の値に変更することが出来れば、このゲームオブジェクトはその時点から移動を開始することになります。
つまり、条件を考えた上での手順としてはこのような制御の流れになります。


1.Ground_Start ゲームオブジェクトの MoveObject スクリプトの MoveSpeed の値を 0 に変更しておく = ゲームスタート時点では移動しない状態になる
2.キャラが初めてバルーンを生成したら、Ground_Start ゲームオブジェクトの MoveObject スクリプトの MoveSpeed の値を 0 ではない値(0.005f)に変更する
3.MoveSpeed の値が 0 以上になったので、Ground_Start ゲームオブジェクトが移動するようになる


 重要なのは【2】の手順です。ここで設定した条件を満たすことが引き金となって、MoveObject スクリプトの MoveSpeed の値が変更されます。

 「キャラが初めてバルーンを生成したら」という条件ですが、ここでは PlayerController スクリプトを修正して、この条件を追加していきます。

 考え方としては、キャラが初めてバルーンを生成した、という条件を判定するための変数が必要になります。
バルーンを生成した、あるいは生成していない、という2つの状態を判定することができればよいのですから、bool 型の変数を作成して、この状態を管理させます。
今回はバルーンを生成したら true、生成していなければ false という状態であるとします。この状態を元に if 文による制御文を作成し、状態に応じて分岐を作ることで制御を行います。

 またこの制御を行うにあたり、MoveObject スクリプトをそのまま変更する方法ではなく、新しく作成する StartChecker スクリプトを挟んで処理を実行させます。
【2】の手順の内容は、次のような流れになります。


A.キャラがバルーンを生成すると、PlayerController スクリプトの処理により、「初めてバルーンを生成した」という判定が行われる
B.【A】の処理が行われると、新しく作成する StartChecker スクリプトの、MoveObject スクリプトの MoveSpeed 変数を変更するメソッドが呼び出されて処理を実行するようにする
C.【B】の処理が行われると、StartChecker スクリプトのメソッドが実行されて、この処理によって、Ground_Start ゲームオブジェクトの MoveObject スクリプトの MoveSpeed 変数が変更される

 それでは StartChecker スクリプトを作成します。


StartChecker スクリプトを作成する


 Ground_Start ゲームオブジェクトにアタッチするスクリプトです。
SetInitialSpeed メソッドを呼び出すことによって、このスクリプトが紐づけを持っている MoveObject スクリプトにアクセスし、MoveSpeed 変数を変更することが出来ます。
 

StartChecker.cs

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



StartChecker スクリプトを Ground_Start ゲームオブジェクトにアタッチして、MoveObject スクリプトの設定を行う


 StartChecker スクリプトを作成したらセーブし、ヒエラルキーにある Ground_Start ゲームオブジェクトにドラッグアンドドロップしてアタッチします。


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


 
 StartChecker スクリプトの Start メソッドではGetComponentメソッドを行い、MoveObject スクリプトを取得します。
この処理は、StartChecker スクリプトのアタッチされているゲームオブジェクトにアタッチされている、MoveObject スクリプトを取得して、用意した変数に代入するという処理になります。
GetComponent メソッドの処理によって変数に MoveObject スクリプトの情報が代入されることで、この変数を通じて、MoveObject スクリプトを操作出来るようになります。


PlayerController スクリプトを修正して、初めてバルーンを生成した際に実行する処理を追加する

 
 宣言フィールドに新しく2つの変数を追加します。

 初めてバルーンを生成した、という情報を判定するために、bool 型の isFirstGenerateBallon 変数を用意します。
今回の場合、false の状態が未生成、初めて生成した際には true になるように、自分で変数の利用方法について設定を考えておきます。
GenerateBallon メソッド内に新しく追加する if 文にこの変数を使うことで、初めてバルーンを生成したかどうかによる制御を行います。

 もしも初めてバルーンを生成したのであれば、StartChecker スクリプト内に用意してある SetInitialSpeed メソッドを呼び出して実行させます。
このメソッドを実行するには、StartChecker スクリプトの情報が必要になりますので、[SerializeField]属性を持つ startChecker 変数を用意して
インスペクターからアサインし、 StartChecker スクリプトと PlayerController スクリプトとを紐づけしておきます。


PlayerController.cs

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



Yuko_Player ゲームオブジェクトの PlayerController スクリプトの設定を行う


 PlayerController スクリプトを修正したらセーブを行い、Yuko_Player ゲームオブジェクトを選択して、PlayerController スクリプトを確認します。
新しく追加した2つの変数のアサイン情報が表示されますので、startChecker 変数について設定を行います。isFirstGenerateBallon 変数は変更なしで問題ありません。

 なお下記の画像には startChecker 変数のアサイン用の参考画像です。
そのため isFirstGenerateBallon 変数は表示されていませんが、自分の Unity の画面の方を参考にしてください。
isFirstGenerateBallon 変数も表示されていることが正常です。


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



 startChecker 変数には、ゲームオブジェクトにアタッチされている StartChecker スクリプトの情報をアサインします。
このスクリプトは先ほど Ground_Start ゲームオブジェクトにアタッチしていますので、ヒエラルキーにある Ground_Start ゲームオブジェクトを選択して
ドラッグアンドドロップしてアサインしてください。自動的に、Ground_Start ゲームオブジェクトの持つ StartChecker スクリプトが情報として startChecker 変数に代入されます


<手順動画 Ground_Start ゲームオブジェクトにアタッチされている StartChecker スクリプトをドラッグアンドドロップしてアサインする>
https://gyazo.com/bf3242deb1393c51a498adf77ccaea6d


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



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


 すべての手順が終了しましたので、ゲームを実行して想定している動作になっているかどうかを確認します。

 先ほどの違い、ゲームがスタートしても、Ground_Start ゲームオブジェクトは移動しません。これは MoveObject のMoveSpeed の値が 0 になっているためです。


<実行動画>
https://gyazo.com/209ae4c0885456baf63c523fa56577fe


 バルーンの生成を行ってみてください。Console にデバッグログとして”初回のバルーン生成”の文字列が表示されて
Ground_Start ゲームオブジェクトの MoveObject スクリプトの MoveSpeed の値が 0 から 0.005 に変更になれば成功です。

 バルーン生成と同時にスタート地点の地面が動き始めるはずです。


<実行動画>
https://gyazo.com/42b7fe871baa7e74690f26aaea727f03


 スクリプトを通じて、別のゲームオブジェクトのスクリプトを操作することによって、このようにゲーム内にあるゲームオブジェクトの制御を行うことが出来るようになります。


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

 次は 手順14 −障害物の設置・移動− です。