【Unity】2Dシューティングを作ってみる話 #4

記事をご覧いただき、誠にありがとうございます。
投稿主の無能です。

前回までで弾が出せるようになったので、今回はその弾を消す仕組みを作りたいと思います。

オブジェクトを消す仕組みを作る

オブジェクトを消す仕組みは、それこそ多岐に渡ります。

今回だと弾を消すので、弾が発射されてから何秒後に消えるだったり、カメラの画角外に出たら消すなんて方法もあります。

でも一応Roll a Ballをやった以上は、Roll a Ballで作った仕組みを使って、不要なオブジェクトを消す仕組みを作りたいと思います。

オブジェクトを消す仕組みは単純で、Roll a Ballで使ったように「オブジェクトが何かに接触したら消える」という方法にしていきます。

方針が決まったので、早速やっていきましょう。

オブジェクトに触れる壁を作成する

何かに接触したら消す、という仕組み上、接触するオブジェクトを用意する必要があります。

ですので、その触れたら消える壁のようなものを作っていきます。

まずは空のオブジェクトを作成し、名前を「ObjectDestroyer」とします。

そう言えば、Hierarchyビューの+ボタンでも作成できますので、今回はそちらで作っています。
従来通りの作成の仕方でもどちらでも構いません。

Create Emptyで空のオブジェクトを作成
(今回はHierarchyビューの+ボタンで作成)

名前を「ObjectDestroyer」にする

ObjectDestroyerも実態が無いので分かり辛いですが、後程分かりやすくなるので大丈夫です。

Transoformのpositionが全て0になっていることを確認したら、次にBox Collider 2Dを追加します。

末尾に2Dの付いていないBox Colliderでは機能しないので注意してください。

Box Collider 2Dをアタッチする

Box Collider 2Dをアタッチしたら、以前PlayerなどにアタッチしたColliderと同様に、is Triggerにチェックします。

is Triggerにチェックする

そして、Colliderのサイズを引き伸ばしてやります。

ObjectDestroyerでは、取り敢えず発射した弾が消えるようにしたいので、カメラの画角外の右側に設置します。

Box Collider 2DのSizeのyを伸ばします。
後でいくらでも調整できるので、15くらいで大丈夫です。

Box Collider 2DのSizeのyを15にする

すると、Box Collider 2Dの範囲を示す緑の枠線が表示されました。
これで視認できるようになりましたね。

ではObjectDestroyerを右側に持っていきます。

今回は15にしました。

ObjectDestroyerのpositionのxを15にした

右側へ持っていけましたね。

このままだとOn Triggerにチェックしたので通過するだけになります。

次はスクリプトでオブジェクトに接触したら消える処理を書いていきます。

新たにScriptsフォルダにスクリプトを作成し、名前を「ObjectDestroyer」とします。

今回もHierarchyビューと同様に、Projectビューの+ボタンからスクリプトを作成しています。

Projectビューの+ボタンからスクリプトを作成

名前を「ObjectDestroyer」とする

早速スクリプトをVisual Studioで開いて、コードを記述します。

今回はこのようになりました。
using UnityEngine;

public class ObjectDestroyer : MonoBehaviour
{
    // オブジェクトが接触したら消す
    private void OnTriggerEnter2D(Collider2D collision)
    {
        // オブジェクトのタグがPlayerではない場合
        if (!collision.gameObject.CompareTag("Player"))
        {
            // 接触してきたオブジェクトを削除
            Destroy(collision.gameObject);
        }
    }
}
では見ていきましょう。

タグを付けて破棄するオブジェクトを判別する

この書き方は、ほぼ定型文のようなものですね。

コメントだけで動きが分かりそうなものですが、まあ見ていきましょう。

OnTriggerEnter2D関数で、接触判定をしています。
注意点は2Dと言う明記があることです。

OnTriggerEnterだと、Box Collider 2Dと同様に反応してくれないので、もし反応しないという事であれば、まずは2DがBox Colliderと関数に付いているかを確認しましょう。

それで、if文の条件式では、接触してきたオブジェクトのタグが「Player以外の場合」としています。

これはどう言った理由なのか?を説明する前に、ちょっと考えれば理由が分かると思います。

このObjectDestroyerはカメラの画角外の設置してあるので、カメラの画角内から出られないPlayerが接触することは、移動制限が解かれない限りありえない状態です。

そしてこの先では、撃ち落とすことが目的となる敵オブジェクトの出現してきます。

勿論、敵も弾を発射してくる予定でいます。

という事は、敵も敵の弾もタグによる判別が必要になります。

ここまで来ればお分かりの通り、一括でオブジェクトを破棄できたら良いですよね。
その一括で破棄出来る要素となるのが、カメラの画角内から出られないPlayerとなるのです。

そうするとPlayerBulletも、この先に作る敵オブジェクトも、一括で破棄できるようになります。

作り方や判別方法は前述の通り千差万別ですが、この方法が後からでも追加や削除も柔軟に対応できるので、この方法を採りました。

ではObjectDestroyerスクリプトをアタッチします。

ObjectDestroyerスクリプトをアタッチ

スクリプトをアタッチしたら、判別出来るようにPlayerBulletにタグを付けます。

タグは「PlayerBullet」を新規作成してこのタグをプレハブに付けます。

タグを追加する

PlayerBulletタグを新規作成

PlayerBulletプレハブにタグを設定する

ではゲームを実行して確認してみましょう。

ゲームを実行して弾を発射すると、ObjectDestroyerに接触した弾が消えるようになった

これで問題無さそうですね。

ObjectDestroyerで四方を囲む

あとはObjectDestroyerを複製して、四方を囲めばPlayer以外のオブジェクトが消える仕組みが出来上がります。

まずは空のオブジェクトを作成して、名前を「ObjectDestroyerWall」とします。
ObjectDestroyerをまとめるための親オブジェクトです。

念のためpositionが全て0であるかを確認します。

「ObjectDestroyerWall」という空のオブジェクトを作成

positionが0であることを確認する

ObjectDestroyerWallを作成したら、ObjectDestroyerを子オブジェクトにして名前を「ObjectDestroyer_Right」に変更します。
四方を囲むので、囲む方角が分かるようにしています。

ObjectDestroyerを子オブジェクトにして名前をObjectDestroyer_Rightに変更

あとは残る三方を複製すればOKです。

こんな感じになります。

ObjectDestroyerで四方を囲む

サイズやBox Collider 2Dの大きさは自由ですが、必ず隙間が出来ないように囲う事を忘れないようにしてください。
もし隙間からオブジェクトが出てしまうと、ゲーム実行中はずっとオブジェクトが存在しているので、余分なリソースを食ってしまいます。

これでPlayer以外のオブジェクトを消す仕組みが出来ました。

まとめ

今回は
  • オブジェクトが接触する壁のようなオブジェクトを作成した
  • 新たにオブジェクトが消えるスクリプトを作成した
  • オブジェクトが消える壁で四方を囲んだ
という事をやりました。

次回は、背景が黒一色で寂しいので、背景を作りたいと思います。

では、また次回!

コメント