i-school - 2Dタップシューティングゲーム 手順9
 以下の内容で順番に実装を進めていきます。

手順9 −エネミーの作成と制御−
18.Canvas内にエネミー用ゲームオブジェクトを配置し、設定する
19.EnemyController スクリプトを作成し、エネミーの制御を行う



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

 ・Transform.Translate メソッド



18.Canvas内にエネミー用ゲームオブジェクトを配置し、設定する

1.設計


 プレイヤー役のキャラと同じように、エネミー役のゲームオブジェクトも Canvas 内に作成していきます。

 最初にキャラの位置を変更し、エネミーの作成の邪魔にならない位置に変更します。
その上で、エネミーの作成を行います。

 エネミーのゲームオブジェクトの設計は、キャラを作成した場合と同じ作りにします。
 
 エネミーの情報を管理するフォルダ役のゲームオブジェクトを作成し、その子オブジェクトとして、エネミーの画像情報を管理するゲームオブジェクトを作成する手法です。
今後、エネミーの情報を追加していく場合には、子オブジェクトとして、ゲームオブジェクト単位で情報を追加していくことが出来ます。


2.PlayerSet ゲームオブジェクトの位置を変更する


 エネミーを作成するにあたり、邪魔にならないようにキャラの位置を移動させておきます。

 PlayerSet ゲームオブジェクトの RectTransfom コンポーネント の Position Y の値を -730 に変更してください
Unity では、Sceneビューの中央位置が X = 0, Y = 0 の値になっていますので、Y 軸をマイナス方向にするとゲームオブジェクトは下方向に移動することになります。
Sceneビューで直接操作をしても構いません。


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



SceneビューとGameビュー画像



 以上で設定は完了です。


3.RawImageChara ゲームオブジェクトの位置を変更する


 この手順はアニメーションするキャラモデルを実装していない場合には不要です。スキップしてください。

 キャラモデルを利用している場合、PlayerSet ゲームオブジェクトだけではキャラの位置は変更になりませんので、RawImageChara ゲームオブジェクトの位置を変更しておきます。
PlayerSet ゲームオブジェクトと同じように、RawImageChara ゲームオブジェクトの RectTransform コンポーネントの Position Y の値を -730 に変更してください


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



SceneビューとGameビュー画像



 以上で設定は完了です。


4.Canvas ゲームオブジェクトの子オブジェクトとして EnemySet ゲームオブジェクトを作成する


 Canvas ゲームオブジェクトの上で右クリックをしてメニューを開き、Create Empty を選択します
新しく空のゲームオブジェクト(Transfrom コンポーネントのみアタッチされている、役割のまだないゲームオブジェクト)が作成されますので、名前を EnemySet に変更します。
EnemySet ゲームオブジェクトは、エネミーに関連するゲームオブジェクト群をまとめておくための、フォルダ役のゲームオブジェクトです。


EnemySet ゲームオブジェクト ヒエラルキー画像



 EnemySet ゲームオブジェクトを選択して、RectTransform コンポーネントがアタッチされているか確認します。
Canvas ゲームオブジェクトに含まれるオブジェクトは Transform コンポーネントではなく、RectTransform コンポーネントによって位置情報を管理しています
もしも通常の Transform コンポーネントがアタッチされている場合には、再度作り直してください。


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



EnemySet ゲームオブジェクト Sceneビュー画像(Sceneビューの中央にある)



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


5.EnemySet ゲームオブジェクトの子オブジェクトとして、imgEnemy ゲームオブジェクトを作成する


 EnemySet ゲームオブジェクトの上で右クリックをしてメニューを開き、UI => Image を選択します
Sceneビュー内の中央に、Imgae コンポーネントがアタッチされた白いゲームオブジェクトが新しく作成されますので、名前を imgEnemy に変更します。


imgEnemy ゲームオブジェクト ヒエラルキー画像


imgEnemy ゲームオブジェクトは、ゲームに登場するエネミー役の画像表示の役割を持ちます。


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



imgEnemy ゲームオブジェクト Sceneビュー画像(真ん中の白いゲームオブジェクト)



 EnemySet ゲームオブジェクトの子オブジェクトとして設置されているか、確認した後、次の設定の手順へ移ります。


6.エネミー用の画像ファイルを Unity にインポートする


 エネミー用の画像ファイルを準備します。自由な画像を設定しましょう。
今回のプロジェクトでは、ぴぽや様の画像を利用させていただいています。無料でダウンロードできますが、しっかりと利用規約を守って利用しましょう。


ぴぽや様 エネミーイラスト
https://pipoya.net/sozai/assets/enemyillust/enemy-...



 ダウンロードしたファイルは多くの場合、圧縮されていますので、まずは解凍して使用できる状態にします。
 
 Unity へ画像ファイルをするには、Assets 内に対象のファイルをドラッグアンドドロップをすればインポートできます。
インポート前に、Project 内に画像ファイル用の Textures フォルダ内に Enemy フォルダを作成して用意しておくと細分化でき、管理がしやすくなります。

 先の手順を考えつつ、どのようにすればプロジェクトの管理しやすいかを考えながら操作を行うようにしていきましょう。


フォルダ画像



 画像ファイルですが、ダウンロードしたファイルすべてをインポートする必要はありません。
まずはエネミーの画像として利用したいファイルを1〜数枚、Unity へインポートしてください。


7.imgEnemy ゲームオブジェクトの設定を行う


 imgEnemy ゲームオブジェクトの設定を行っていきます。最初に画像を設定します。
imgEnemy ゲームオブジェクトのインスペクターを確認し、Image コンポーネントの Source Image の部分に画像を設定します。

 インポートした画像ファイルを、Source Image の欄までドラッグアンドドロップしてアサインしてください
画像が登録されて、Sceneビューに反映されます。


インスペクター画像



SceneビューとGameビュー画像(白いゲームオブジェクトではなくなっている)



 画像の設定が終了したら、Image コンポーネントの Raycast Target のスイッチを外してオフにしておいてください



 画像を設定したら、大きさを調整します。

 imgEnemy ゲームオブジェクトの RectTransfrom コンポーネント内にある、Scale の値を (1, 1, 1) => (4, 4, 4) に変更してください。
現在のサイズが4倍になります。今回も設定しながら、Gameビューにどのように映っているかを確認しておきます。


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



imgEnemy ゲームオブジェクト Sceneビュー画像



imgEnemy ゲームオブジェクト Gameビュー画像



 以上で設定は完了です。
キャラのサイズは後でも調整できますので、画面を確認しながら調整をしましょう。


19.EnemyController スクリプトを作成し、エネミーの制御を行う

1.設計


 作成したエネミーの制御をスクリプトを通じて行えるようにします。

 PlayerController スクリプトと同じように、Scripts フォルダ内に EnemyController スクリプトを作成して、その中に、エネミーの制御を管理する処理を記述します。
スクリプトが完成したら、EnemyController スクリプトをエネミーのゲームオブジェクトにアタッチすることで、スクリプトを実行することが出来ます。
 


 制御、といっても色々な状態が含まれます。そこでまずは、エネミーの移動処理を実装しようと思います。

 「エネミーの移動」とはゲーム内の言葉ですが、これをUnity側、すなわち、プログラムとして考えてみると、「ゲーム内のゲームオブジェクトの座標の変更」と同義です。
つまり、エネミーのゲームオブジェクトの座標情報をプログラムを通じて更新していくことが出来れば、それはゲーム上では「エネミーが移動している」ように見せることが出来ます。

 プログラムのロジックを考える際には、この日本語の内容をプログラムに置き換えるイメージが非常に重要になります。



 エネミーの移動については、現在設置した位置から、徐々に、キャラのいる下方向へと移動させる設計とします。
そのため、一瞬でキャラの位置に移動してしまうようでは、制御失敗です。

 「徐々に」ということは、継続して座標の変更処理を行う必要があります。Unity には Update メソッドという、継続的な処理を行うことに適したメソッドが用意されています。
今回はこちらを利用するように設計を行います。

 ここまでの状態を、EnemyController スクリプトを実際に作成し、日本語コメントとして、実装したい処理の内容を記述してみてください。
次のようなイメージになると思います。
 

    void Update() {

    // このスクリプトがアタッチしているゲームオブジェクトを徐々に移動する

    }

 このように準備をします。それから、この日本語の内容を、プログラムとして考えて下に記述するようにしてみてください。
他にもロジックを作っていく方法はありますが、コメントを記述しておいてからプログラムに直していく手法がわかりやすく、コメントも残るため、やりやすい方法になります。


 移動の処理ですが、Unity の用意している情報に Transform クラスの扱う、Tranlate メソッドでの移動があります。
これは、移動させたいゲームオブジェクトの Transform コンポーネントの情報を取得し、
その上で Tranlate メソッドを実行することによって、そのゲームオブジェクトの座標情報を変更することができる処理になります。

 Tranlate メソッドを1回実行しただけでは座標の変更も1回だけですが、短い座標の変更を何回も継続的に行うことによって座標の更新を行い
その結果、ゲームオブジェクトを徐々に移動をさせる処理にすることが出来ます。

 次のメソッドの内容を確認した上で、実際に Update メソッドに処理を記述し、エネミーの移動を実装してみましょう。


2.<Transform.Translate メソッド>


 Unity の用意している、Transform クラスが扱うことが出来るメソッドの1つです。
ゲームオブジェクトの位置を、Tranlate メソッドの引数で指定している値ずつ、座標を移動させることが出来ます。

参考サイト
Unity公式スクリプトリファレンス
Transform.Translate
https://docs.unity3d.com/ja/current/ScriptReferenc...
FREE SWORDER 様
【Unity基礎】transformを変更してオブジェクトを移動させる2つの方法
https://freesworder.net/unity-transform-move/


3.EnemyController スクリプトを作成し、エネミーを上方向からプレイヤーのいる地点へ移動させる制御を追加する


 設計とメソッドの説明やサイトの情報を確認しながら、自分で移動の処理を書いてみましょう。


EnemyController.cs



 スクリプトを作成したらセーブしてください。


4.Enemy ゲームオブジェクトに EnemyController スクリプトをアタッチする


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

 スクリプトをアタッチしたら、対象のゲームオブジェクトのインスペクターを確認してください。
EnemyController スクリプトと一緒に、CapsuleCollider2D コンポーネントもアタッチされます。


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


 それでは CapsuleCollider2D コンポーネントの設定を行います。


5.EnemySet ゲームオブジェクトの設定を行う


 EnemySet ゲームオブジェクトのインスペクターより、CapsuleCollider2D コンポーネントの設定を行います。
これは次の手順で、キャラが発射するバレットとエネミーとの間で接触判定を行うために利用する情報になります。

 最初に、IsTrigger の部分にチェックを入れて、オンの状態に設定します。

 続いて、コライダーのサイズを変更します。
かなり小さい状態になっていますので、Sceneビューや、下記のインスペクター画像のサイズを参考にして
自分のエネミーの画像に見合ったサイズに変更してください。

 コライダーの形状がカプセル状であるため、あまり細かく設定しすぎないように、大体のサイズにしましょう。


EnemySet ゲームオブジェクト インスペクター画像(サイズは参考用。あくまでも自分で設定した画像に見合うサイズにすること)



コライダー Sceneビュー画像



 以上で設定は完了です。


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


 スクリプトをゲームオブジェクトにアタッチしたら、ゲームを実行してください。
エネミーが下方向に移動を開始すれば、スクリプトからエネミーの制御が行えていることになります。


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


 ずっとゲームを実行しているとわかりますが、ゲーム画面外に移動しても、エネミーが移動を止めることはありません
また、途中で消えるようなこともありません。これはスクリプトで制御している情報が移動を行う処理しかないためですので、当然といえば当然のことになります。

 ですが、できればゲーム画面外に移動したエネミーについては、そのまま消えてしまった方が、ゲームとしても、また管理する場合を考えても制御しやすいです。

 それでは続いて、EnemyController スクリプトを修正し、ある一定の位置までエネミーが移動をしたら、エネミーを破壊する処理を実装しましょう。


7.EnemyController スクリプトを修正し、一定地点までエネミーが移動したら破壊する制御を追加する


 まずは、「一定地点」をどこにするか、それを設定しましょう。

 実際に、エネミーをSceneビューで下方向に移動させて Transform コンポーネントの Position の Y の情報を見ていてください。
このとき、ゲーム画面の下方向の外側にエネミーを移動させた際に、ゲーム画面からエネミーが見えなくなったときの Y 軸の座標が「一定地点」の候補となります。
つまり、エネミーが画面から見えなくなってから消えるようにしたいためです。

 画面の解像度(サイズ)にもよりますが、動かしていくと、ゲーム画面のエネミーが見えなくなる Y 軸の座標は -1450 〜 -1500 前後です。
つまり、この値よりもマイナス方向に大きな値になれば、それはゲーム画面より外となる座標ということになります。

 今回はこの値を「一定地点」とします。仮に -1450 〜 -1500 前後を設定値として考えておきます。
実際には、ご自分のゲーム画面の解像度に合わせて、エネミーが画面から完全に消える位置を利用してください。



 続いては、この一定地点を利用した制御文を考えていきます。

もしも〜になったら」「〜の場合」「〜したら」という文章は「条件」という言葉で実装を考えます。

 制御文の多くは if 文によって、上記のような「〜したら」という条件式のロジックをプログラムで作成し、プログラムの制御を行うことが出来ます。
今回も if 文と、その条件となる式を考えて設計をしてみます。

 今回の条件となるものは、「一定地点までエネミーが移動したら」の部分になります。
エネミーの移動の処理は Update メソッド内に記述されていますので、この if 文の処理も同じく Update メソッドに用意する必要があります。

 また日本語の処理を、別の単語として読み替えてみることも重要です。
「一定地点までエネミーが移動したら」とはつまり、「このゲームオブジェクトの位置が一定値を超えたら」ともなります。
一定地点については情報が用意できていますので、あとは、ゲームオブジェクトの位置情報の確認が取れれば大丈夫そうです。

 エネミーの位置情報と一口にいっても、RectTransform コンポーネントの管理する位置の情報は Position ですので、3つの軸情報があります。
今回必要な位置情報はこれらすべてなのか、あるいはある値だけでいいのか、それも考えてみて条件式を作っていきます。



 今回も、実装したい処理の内容を、自分で考えてコメントを記述してみましょう。ロジックを組み立てていく目安にもなります。
例えば、今回は Update メソッド内に処理を追加することがわかっていますので、その中に対象となる処理のコメントを記述していく形です。

<コメント例>
    void Update() {

    // このスクリプトがアタッチしているゲームオブジェクトを徐々に移動する


        // 一定地点までエネミーが移動したら = このゲームオブジェクトの位置が一定値を超えたら


        //  このスクリプトがアタッチしているゲームオブジェクトを破壊する

}

 上記のコメントを参考にしながら、どのような制御を条件とすれば、エネミーを破壊できるようになるのか、考えてみてください。


EnemyController.cs


 スクリプトを修正したら、忘れずにセーブを行います。


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


 それではゲームを実行して、エネミーの制御の確認を行っていきます。
一定地点として指定した座標までエネミーが移動したら破壊されるように動けば、制御成功です。


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


 制御が成功したら、エネミーのスタート位置を別の地点に変えて試してみてください。同じように、指定された一定地点で破壊されていることが分かります。


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

 次は 手順10 −バレットとエネミーとの接触判定の実装− です。