【Unity】《第3回》敵を倒してエフェクトをつけよう!(当たり判定)|シューティングゲームを作ろう
Unity入門のゲーム作成チュートリアル第4弾の「城防衛シューティングゲーム」です!
襲来してくる敵を大砲で迎撃し、城を守りきることができれば勝利というゲームを作成していきます。
※そのほかのゲーム作成記事に関する情報は以下記事をご参考ください。
参考記事)Unity入門オリジナルチュートリアル集
第3回の今回は「敵を倒してエフェクトをつける」方法をご紹介します。
敵と弾が衝突したときの当たり判定と当たったときのエフェクトを実装します。
概要
前回の「《第2回》敵を自動生成する」では以下の処理を作成してきました。
- 敵プレハブの作成
- 敵生成スクリプト作成
第2回までをまだ完成させていない!という方は「《第1回》大砲で弾を撃つ」「《第2回》敵を自動生成する」を参考にして処理を完成させてください。
第3回の今回は以下の処理を作成していきます。
- 敵と大砲の弾の当たり判定
- 当たり判定時の処理(敵・弾の削除&エフェクト)
以上を中心に進めます。
手順としては、
- 敵スクリプトに当たり判定メソッドを追加する
- 当たり判定時の処理を実装する
の順番で進めます。今回もできる限りわかりやすく解説していきますのでぜひご参考ください。
敵と大砲の弾の当たり判定を実装する
敵と大砲の弾の当たり判定を実装します。
方法はシンプルで、生成された敵のスクリプトに大砲の弾との当たり判定を記述するのみです。
当たり判定スクリプトを作成する
当たり判定スクリプトを作成する前に、Bulletプレハブのタグを「Bullet」に変更します。
Bulletプレハブを選択してインスペクターウィンドウの上部のTagから「Bullet」タグに変更してください。
変更方法は以下記事内の「タグ付けをする」をご参考ください。
参考記事)敵プレハブを作成する→「タグ付けをする」
次に敵にアタッチする当たり判定スクリプトを作成します。
Scriptsフォルダに「HitController」スクリプトを作成し、以下のように変更してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class HitController : MonoBehaviour { //当たり判定メソッド private void OnCollisionEnter(Collision collision) { //衝突したオブジェクトがBullet(大砲の弾)だったとき if(collision.gameObject.CompareTag("Bullet")) { Debug.Log("敵と弾が衝突しました!!!"); } } } |
プログラムを解説します。
8行目を見てください。
1 |
private void OnCollisionEnter(Collision collision) |
「OnCollisionEnter(Collision collision)」はスクリプトをアタッチしているオブジェクトに物理的に衝突したオブジェクトの情報を引数Collision型のcollisionとして渡します。
簡単に言うと、衝突したオブジェクト情報を取得するメソッドです。
11行目を見てください。
1 |
if(collision.gameObject.CompareTag("Bullet")) |
このif文は衝突したオブジェクトのタグをCompareTagを用いて「Bullet」であるかどうかを判定しています。
if文の中では詳しい処理は記述せずにコンソールに衝突したことがわかるようにしています。
それではこのスクリプトをEnemyプレハブにアタッチして確認してみましょう。
※プレハブへのスクリプトアタッチ方法は以下GIF参照(※GIFのスクリプトはここまで作成してきたものと異なります)
敵と弾が当たっていることを認識させることができました。
たったこれだけの記述で当たり判定を実装できるUnityは素晴らしいですね!
これでif文の中身を書き換えれば様々な処理を実装することができます。
当たり判定時の処理を実装する
当たり判定を実現できましたので、ここからは当たったときの処理を実装していきます。
敵と弾を削除する
まずは弾が当たったときに敵と弾を削除します。
先ほど作成したHitControllerスクリプトを以下のように書き換えてください。(変更部分をハイライトしています)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class HitController : MonoBehaviour { //当たり判定メソッド private void OnCollisionEnter(Collision collision) { //衝突したオブジェクトがBullet(大砲の弾)だったとき if(collision.gameObject.CompareTag("Bullet")) { //敵(スクリプトがアタッチされているオブジェクト自身)を削除 Destroy(gameObject); //弾(引数オブジェクト)を削除 Destroy(collision.gameObject); } } } |
ハイライトされた部分を見てください。
「Destroy(Object)」は引数として渡したオブジェクトを削除します。これによって敵と弾を削除することができます。
実際に実行して確認してみましょう。
当たり判定に続けてとても簡単に削除を実装できることがおわかりいただけましたでしょうか。
Unityにはこのような便利なメソッドがたくさんあります。難しく考えていたことがたったの一文で実装できてしまうことが多々ありますので、悩んだときはUnity公式レファレンスを探してみることをおすすめします。
エフェクトを作成する
次に敵と弾が衝突したときのエフェクトを作成します。
ここでは既存のエフェクトを利用します。「Unity Particle Pack 5.x」をダウンロード&インポートしてください。
これらのエフェクトはほとんどが「パーティクル」を用いて作成されています。オリジナルのエフェクトを作成してみたい!という方は以下記事をご参考ください。
参考記事)パーティクル徹底解説
まずはスクリプトを書き換えます。先ほど作成したHitControllerスクリプトを以下のように変更してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class HitController : MonoBehaviour { //倒したときのエフェクト public GameObject breakEffect; //当たり判定メソッド private void OnCollisionEnter(Collision collision) { //衝突したオブジェクトがBullet(大砲の弾)だったとき if(collision.gameObject.CompareTag("Bullet")) { //敵(スクリプトがアタッチされているオブジェクト自身)を削除 Destroy(gameObject); //弾(引数オブジェクト)を削除 Destroy(collision.gameObject); //エフェクトを発生させる GenerateEffect(); } } //エフェクトを生成する void GenerateEffect() { //エフェクトを生成する GameObject effect = Instantiate(breakEffect) as GameObject; //エフェクトが発生する場所を決定する(敵オブジェクトの場所) effect.transform.position = gameObject.transform.position; } } |
プログラムを解説します。
8行目では今回発生させるエフェクトを格納するための変数を定義しています。publicにしているのはオブジェクトをUnityエディタでアタッチできるようにするためです。
22行目ではエフェクトを生成するメソッド「GenerateEffect()」を呼び出しています。
27行目〜34行目を見てください。
1 2 3 4 5 6 7 8 |
//エフェクトを生成する void GenerateEffect() { //エフェクトを生成する GameObject effect = Instantiate(breakEffect) as GameObject; //エフェクトが発生する場所を決定する(敵オブジェクトの場所) effect.transform.position = gameObject.transform.position; } |
このメソッドはアタッチしたプレハブ(発生させたいエフェクト)をインスタンス化(生成)して発生場所を決定させるメソッドです。
インスタンス化等のゲームオブジェクトに関する情報について詳しく知りたい方は以下記事をご参考ください。
参考記事)ゲームオブジェクトについて
これでエフェクトが生成されるようになります。
次に使用するエフェクトを少しだけ編集します。今回はEffectExamples→Fire&Explosion Effects→Prefabs→「EnergyExplosion」を使用します。
このプレハブをそのまま編集してしまうと再びこのプレハブを使用するときに不便なので、一旦コピーして別のプレハブとして編集します。
手順は以下の通りです。
- EnergyExplosionをシーンに呼び出す
- 右クリック→Unpack Prefabを選択してプレハブ化を解除する
- 名前を「EnemyExplosion」に変更する
- EnemyExplosionを自前のPrefabsフォルダにドラッグ&ドロップしてプレハブ化
これでオリジナルのプレハブに変更されました。
プレハブ化したらシーンにあるEnemyExplosionは邪魔ですので削除しておきましょう。
次にこのプレハブが生成されてから一定時間がすぎると自動的に生成したプレハブを削除するスクリプトを作成します。
生成したプレハブを削除する理由をここでは深く言及しませんが、シーン(メモリ)に使わなくなったオブジェクトを残しておくことはUnityに限らず、アプリケーション・システムにとって良いことではありません。使わなくなったオブジェクトはこまめに削除することをおすすめします。
それではScriptsフォルダに「EffectBreaker」スクリプトを作成して、以下のように変更してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class EffectBreaker : MonoBehaviour { // Start is called before the first frame update void Start() { //エフェクトが生成されて2秒後にオブジェクトを削除する Invoke("BreakEffect",2.0f); } //エフェクト(自分自身)を削除する void BreakEffect() { Destroy(gameObject); } } |
仕組みはいたってシンプルです。
まずはこのスクリプトをアタッチしているオブジェクトが生成されたときに呼び出されるStartメソッドの中で「Invoke(メソッド名,時間)」を利用して一定時間後に指定したメソッドを呼び出します。
「Invoke」は第一引数にString型でメソッド名を指定します。第二引数には指定したメソッドを呼び出したい時間を指定します。
ここでは自分自身を削除するメソッド「BreakEffect」を「2秒後」に呼び出すという仕組みにしています。
このスクリプトを先ほど作成したEnemyExplosionプレハブにアタッチすれば完了です。(以下GIF参照)
これでオブジェクトが生成された2秒後にそのオブジェクトを削除する仕組みを作成することができました。
最後に完成したEnemyExplosionプレハブを敵プレハブのHitControllerスクリプトにアタッチして完成です。(以下GIF参照)
それでは実際に実行して確認してみましょう。
敵オブジェクトが破壊されるタイミングでエフェクトが発生し、ヒエラルキーウィンドウでは生成されたエフェクト(EnemyExplosion)が一定時間後に削除されていることが確認できました。
このように当たり判定を用いてオブジェクトを削除したり、エフェクトをつけたりすることができます。
まとめ
いかがでしたでしょうか。
今回は敵を倒してエフェクトをつける方法についてご紹介してきました。
当たり判定というと難しそうに見えますが、ここまで進めてきた方にとってはもう難しいものと感じることはなくなったのではないでしょうか。
また、エフェクトについても当たり判定のメソッドと組み合わせることで非常に簡単に実装することができます。オリジナルのエフェクトを作成したりしてオリジナリティを出すと、より楽しく開発を進めることができるのでぜひチャレンジしてみてください!
本記事を通じて皆様のUnityライフがもっと充実したものになれば幸いです!
この記事はいかがでしたか?
もし「参考になった」「面白かった」という場合は、応援シェアお願いします!