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

手順12 ープレイヤーの拠点の実装ー
25.Canvas内にプレイヤーの拠点用のゲームオブジェクトを配置し、設定する
26.DefenseBase スクリプトを作成し、エネミーが侵入した際にエネミーを破壊する処理を実装する



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

 ・OnTriggerEnter2D メソッド、Tag の復習を行う



25.Canvas内にプレイヤーの拠点用のゲームオブジェクトを配置し、設定する

1.設計


 この手順では、Canvas ゲームオブジェクト内にプレイヤーの拠点を製作していきます。この地点にエネミーが到達するとダメージを受けるシステムになります。
このゲームオブジェクトもゲーム画面に映る必要のあるゲームオブジェクトですので、 Canvas ゲームオブジェクトの子オブジェクトとしてゲームオブジェクトを作成していきます。

 ここでは、拠点を管理するためのフォルダ役のゲームオブジェクト、拠点の画像を設定するゲームオブジェクト群、さらにコライダー用のゲームオブジェクトと、
これらを1つずつ順番に作成します。


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


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


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



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


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



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



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


3.DefenseBaseSet ゲームオブジェクトの子オブジェクトとして、imgDamageArea ゲームオブジェクトを作成する


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


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



imgDamageArea ゲームオブジェクトは、プレイヤーの拠点となるエリアの画像表示の役割を持ちます。
この位置までエネミーが到達するとダメージを受けてしまう、その目印となる画像になります。


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



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



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



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


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

 こちらの画像がゲーム画面に適用されるこの位置にエネミーが到達して侵入するとダメージを受ける目印の画像となりますので、イメージあった画像を設定します。
インポートされている画像はありませんので、無料の画像を探しダウンロードして Unity にインポートして利用します。

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


インスペクター画像



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



 画像の設定が終了したら、Image コンポーネントの Raycast Target のスイッチを外してオフにしておいてください
また、ImageType が Simple になっていない場合には Simple に変更してください。Slice などの設定になっていると画像が正常に表示されないためです。



 画像を設定したら、次は画像のサイズを調整します。

 imgDamageArea ゲームオブジェクトの RectTransfrom コンポーネント内にある、Position の値を (-480, -816, 0) に変更してください。位置が左下寄りになります。
また、Width の値を 480、 Height の値を 206 に変更してサイズを変更してください。
設定しながら、Gameビューにどのように映っているかを確認しておきます。


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



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



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



 以上で設定は完了です。


5.imgDamageArea ゲームオブジェクトを複製する


 imgDamageArea ゲームオブジェクトを選択して右クリックをしてメニューを開き、Duplicate を選択して、ゲームオブジェクトを複製します。
この手順を2回繰りかえして、合計で3つの imgDamageArea ゲームオブジェクトを作成してください


ヒエラルキー画像



 複製されたゲームオブジェクトは、複製元のゲームオブジェクトの位置にあります。
サイズや画像の設定はそのまま利用できますので、横方向の位置情報だけ変更します

 imgDamageArea (1) ゲームオブジェクトの Position X の値を 0 に変更してください。ゲームオブジェクトが中央に移動します。


imgDamageArea (1) ゲームオブジェクト インスペクター画像



 続いて、imgDamageArea (2) ゲームオブジェクトの Position X の値を 480 に変更してください。ゲームオブジェクトが右側に移動します。


imgDamageArea (2) ゲームオブジェクト インスペクター画像



 これでキレイに横一列にゲームオブジェクトが設置されました。
名前については変更してもよいですし、このままでも問題ありません。


Sceneビュー画像



Gameビュー画像



 以上でダメージ用エリアのゲームオブジェクトの設定は完了です。



6.DefenseBaseSet ゲームオブジェクトの子オブジェクトとして、ColliderDefenseLine ゲームオブジェクトを作成する


 DefenseBaseSet ゲームオブジェクトの上で右クリックをしてメニューを開き、Create Empty を選択します
新しく DefenseBaseSet の子オブジェクトとして空のゲームオブジェクトが作成されますので、名前を ColliderDefenseLine に変更します。
DefenseBaseSet ゲームオブジェクトは、拠点にコライダーを設定する役割を持つゲームオブジェクトです。


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



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



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


 続いて ColliderDefenseLine ゲームオブジェクト の設定を行います。


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


 このゲームオブジェクトの役割はエネミーとの侵入判定を行えるようにするためのコライダーを管理することです。

 imgDamageArea ゲームオブジェクトにコライダーを設定すると、合計3つのゲームオブジェクトにコライダーを設定することになり、
調整が必要になった場合に作業が増えてしまいますので、このゲームオブジェクトを拠点のコライダーして、1つで管理を行うようにします。



 最初に、ゲームオブジェクトのサイズを変更します。横幅は画面の幅と同じサイズに、縦幅は imgDamageArea ゲームオブジェクトの画像に合わせるようにします。
RectTransfom コンポーネントの Width の値を 1440、Height の値を 200 に設定してください。ただし、Widht は自分のゲーム画面の設定に合わせて適宜な値に変更してください。

 また Position Y を -816 に設定し、imgDamageArea ゲームオブジェクトの位置に合わせてください。


インスペクター画像



Sceneビュー画像



 サイズの修正が終了したら、コライダーを設定します。



 ColliderDefenseLine ゲームオブジェクトのインスペクターの一番下にある Add Component ボタンを押して、BoxCollider2D コンポーネントを追加してください。

 最初に、IsTrigger のスイッチのチェックを入れて、オンの状態にしてください。

 次にサイズを調整します。Edit Collider ボタンを押して Sceneビューで変更をするか、Width と Height の値と同じ値に設定をしてください。
 

インスペクター画像



Sceneビュー画像(コライダーが見やすいように、imgDamageArea ゲームオブジェクトの透明度を下げています)



 以上でこのゲームオブジェクトと、拠点用のゲームオブジェクトの設定は完成です。 


26.DefenseBase スクリプトを作成し、エネミーが侵入した際にエネミーを破壊する処理を実装する

1.設計


 拠点のコライダーに対してエネミーの持つコライダーが侵入した際に、侵入判定処理を実行するように設計を考えます。

 考え方は、エネミーとバレットとの侵入判定とまったく同じです。
拠点からみて、バレットに当たるのがエネミーとして考えていけば、同じ設計で実装を行うことが出来ます。

 そのため、この手順で作成する DefenseBase スクリプトは、DefenseBaseSet ゲームオブジェクトにアタッチする前提で作成を行います



 この手順で実装を行う順番を考えましょう。これも、バレットとエネミーの侵入判定処理を作成したときと同じ順番で考えていきます。

 侵入判定の実装方法については、エネミーと同じように、OnTriggerEnter2D メソッドを利用します。
まずは、侵入判定が発生するかを、処理を実装して確認を行います。

 1つ違う点は、コライダーが、DefenseBase ゲームオブジェクトではなく、子オブジェクトとして設定されている部分です。
このような場合、親オブジェクトである DefenseBaseSet ゲームオブジェクトRigidbody2D コンポーネントをアタッチすることによって
親子関係のあるゲームオブジェクトのコライダーの情報を利用することが出来るようになります。

 続いて、エネミーの場合もそうでしたが、このままですとコライダーがあるゲームオブジェクトであればどのゲームオブジェクトでも侵入判定が発生してしまうため、
自分が発射したバレットで侵入判定が発生してしまう恐れがあります。

 これも同じように、エネミー側にエネミーのゲームオブジェクトであると判別するための Tag を設定します。
エネミー側に設定した Tag のゲームオブジェクトが侵入した場合に限り、侵入判定が発生するように処理を追加していきます。

 最後に、エネミーが侵入したら、拠点側に用意した耐久力の値を 10 減らす処理を追加して、エネミーを破壊するようにします。
次の手順では、エネミーに攻撃力の情報を設定し、その値分だけ、耐久力を減算するようにしますので、そのための事前処理になります。


2.DefenseBase スクリプトを作成し、エネミーが侵入した際の判定を行う処理を記述する


 DefenseBaseSet ゲームオブジェクトにアタッチするスクリプトを作成します。
このゲームオブジェクトには子オブジェクトのコライダーを利用する関係上、 Rigidbody2D コンポーネントが必須になります。
このようなときに利用できる属性情報があったと思いますので、そちらを記述してください。

 耐久力の情報を設定するため、新しく宣言フィールドに変数を宣言して追加します。
バレットのときと同じように、public 修飾子で変数を宣言しておくことでインスペクターより値の設定が可能になります。

 耐久力の値をやり取りする際には、今回は固定値で 10 減算します。ということは、整数の計算が行える変数の型で変数を宣言をする必要があることが分かります。
 
 OnTriggerEnter2D メソッドには、エネミーに実装したときと同じように、Debug.Log メソッドを用意して、ゲームオブジェクトが侵入したことを表示させて
処理が正常に動作していることを確認できるようにしておきましょう。

 この一連の手順は、EnemyController スクリプトに実装した内容が非常に役立ちます
スクリプトを見返したり、以前の手順を読み返したりして構いませんので、復習する意味を込めて、まずは、自分で処理を書いてみて実行してみてください。


DefenseBase.cs

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


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


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


 作成した DefenseBase スクリプトを DefenseBaseSet ゲームオブジェクトにドラッグアンドドロップしてアタッチしてください。
属性情報を設定していれば、自動的に Rigidbody2D コンポーネントもアタッチされます。もしも属性情報を記述していない場合には
Add Component ボタンより、Rigidbody2D コンポーネントを追加してください。通常の Rigidbody コンポーネントは動作しませんので、注意してください。



 最初に Rigidbody2D コンポーネントの設定を行います。

 GravityScale の値を 0 にして重力の影響は受けないように設定してください。そうしないと下方向に落下してしまいます。
また、Freeze Rotation の Z のチェックもいれてオンの状態にしてください。オフになっていると、エネミーに侵入された際にゲームオブジェクトが回転してしまいます。


インスペクター画像


 


 続いて、DefenseBase スクリプトの設定を行います。
インスペクター上に Durability 変数が表示されていますので、こちらに耐久力となる値を設定します。
初期値は 0 に設定されています。


インスペクター画像



 スクリプトを変更しなくても、インスペクターより自由に調整することができますので、最初は 100 に設定しておきます。


設定後のインスペクター画像



 以上で設定は完了です。


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


 ここまでの手順が終了しましたので、ゲームを実行してエネミーのゲームオブジェクトが拠点のコライダーの位置まで移動させます。
Console ビューに Debug.Log メソッドで指定したゲームオブジェクトの名前(EnemySet)が表示されれば侵入判定は成功です。


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


 これで無事に侵入判定の処理は実装されました。
次は、この判定の対象をエネミーのみに制限するように、Tag による処理を追加します。

 まずは最初に新しい Tag を登録する必要がありますので、登録と設定を行います。


5.エネミー用の Tag を登録し、EnemySet ゲームオブジェクトに設定する


 EnemySet ゲームオブジェクトのインスペクターのゲームオブジェクト名の左下にある Tag を選択するとプルダウンメニューが開きます。
最初は Untagged(未設定) になっていますので、一番下の Add Tag… を選択して、インスペクターの表示を Tags and Layers に変更します。

 Tags の項目の一番下にプラスボタンがありますので、それを押して、新しく Enemy というタグを作成し、セーブして登録してください。


Tag





 登録が完了したら、エネミーのゲームオブジェクトに Tag を設定します。

 EnemySet ゲームオブジェクトの Tag を選択し、プルダウンメニューから Enemy を選択して登録してください。


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

 

 これで Tag の設定は完了です。


6.DefenseBase スクリプトを修正し、侵入判定の際に、侵入したコライダーがエネミーのコライダーかどうかを判定する処理を追加する


 Tag の設定が完了しましたので、この情報を利用して、侵入したコライダーがエネミーであるのか、それ以外なのかを判定する処理を実装します。

 コメントを記述してから、自分でロジックを考えて処理を記述してみてください。
コメントの参考例も、EnemyController スクリプトの実装が役に立ちますのでそちらを参考に書いてみてください。


DefenseBase.cs

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

 

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


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


 ゲームを実行して、エネミーのゲームオブジェクトを拠点まで移動させてください。
拠点のゲームオブジェクトのコライダーにエネミーのゲームオブジェクトが侵入した際に、Console ビューに Tag の情報(Enemy)が表示されれば制御成功です。


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


 成功したら、その後、EnemySet ゲームオブジェクトの Tag を Untagged に戻して、同じようにゲームを実行して拠点まで移動させてみてください。
今回は Tag で制御を行うようになっていますので、この状態でエネミーのゲームオブジェクトが侵入しても、侵入判定は発生しないようになっています。


 それでは最後の処理を実装しましょう。


8.DefenseBase スクリプトを修正し、侵入判定の際に耐久力の値を 10 減らす処理を追加して、エネミーを破壊する


 この手順での最後の実装になります。

 設計にあったように、エネミーのコライダーを持つゲームオブジェクトが侵入した場合には、耐久力(durability 変数)の値を 10 減算する処理を実装します。
計算結果は Debug.Log メソッドを利用して、Console ビューに、計算結果後の残りの耐久力の値を表示しましょう。

 またこの計算処理とともに、エネミーのゲームオブジェクトを破壊する処理も実装します。

 この部分も、EnemyController スクリプトの実装を思い出してください。
以前の手順をみてもいいですし、EnemyController スクリプトを参考にしても構いませんので、
まずは、ロジック用に日本語のコメントを自分で考えて書いてから、プログラムを記述していきます。


DefenseBase.cs

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


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


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


 すべての手順が終了しましたので、ゲームを実行して、エネミーのゲームオブジェクトを拠点まで移動させてコライダーに侵入させてください。
Console ビューに残りの耐久力の値が表示されれば制御成功です。

 また、拠点のコライダーに侵入したエネミーのゲームオブジェクトが破壊されていれば、こちらも制御成功です。
 

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



<任意>10.EnemyController スクリプトを修正し、ゲーム画面外に出た際に破壊の処理をコメントアウトする

 (この手順は任意です。読んでみて不要な場合にはスキップして構いません。)

 いままでエネミーに対しては、ゲーム画面外になった際に自動的に削除される処理を施していました。

 今回 DefenceBase スクリプトによるエネミー破壊処理が加わりしましたので、ゲーム画面外にエネミーが出ることはなくなりました。
よって、EnemyController の Update メソッド内にある、ゲーム画面外に出たら破壊する、という既存の処理は不要となりました。
 
 忘れないうちに、EnemyController を修正し、該当の処理をコメントアウトしておきましょう。


EnemyController.cs
    void Update() {

    // このスクリプトがアタッチしているゲームオブジェクトを徐々に移動する
        transform.Translate(0, -0.01f, 0);

        // 一定地点までエネミーが移動したら = このゲームオブジェクトの位置が一定値(-1500)を超えたら
        //if (transform.localPosition.y < -1500) {

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

 なおコメントアウトをする場合、移動させる処理自体は必要ですので、処理の内容をきちんと読み解いて、不要な部分だけをコメントアウトするようにしてください。



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

 次は 手順13 ーエネミーの情報を利用してプレイヤーの拠点の耐久力を減算する制御の実装ー です。