おもちゃラボ

Unityで遊びを作ってます

【Unity入門】60分で作るシューティングゲーム 第4回

前回は隕石のPrefabを作って、時間とともに隕石を生成するところまで作りました。

nn-hokuson.hatenablog.com

第4回目の今回は落ちてくる隕石を撃ち落とせるようにしましょう。そのために、弾と隕石の当たり判定をつけていきます。

第1回 ロケットを動かそう
第2回 弾を発射しよう
第3回 隕石を落下させよう
第4回 当たり判定をしよう
第5回 ゲームオーバを判定しよう
第6回 お化粧をしよう

Unityで当たり判定をするには

Unityで当たり判定をする場合には次の2通りがあります。

  1. 自前でオブジェクトの距離を計算する方法
  2. UnityのPhysicsを使う方法

今回の記事では②のPhysicsを使った当たり判定の方法を紹介します。

Physicsで当たり判定をする場合、自前で何かを計算する必要はありません。
オブジェクト同士が衝突した場合にはUnityが特定の関数を呼び出してくれます。
具体的には、衝突したオブジェクトにアタッチされているスクリプトのOnCollisionEnter関数が呼びだされます。

Phsyicsを使って衝突検知をする場合、

  • 両方のオブジェクトにColliderコンポーネントをアタッチ
  • 少なくとも一方にはRigidbodyコンポーネントをアタッチ

する必要があります。

今回は隕石と弾の当たり判定をしたいので、両方のオブジェクトにColliderコンポーネントをアタッチし、弾にはRigidbodyコンポーネントをアタッチしましょう。

Physicsを使った当たり判定についても「Unityの教科書」にイラスト付きで解説しています。是非参考にしてみて下さい。

コンポーネントをアタッチしよう

 まずは隕石にColliderコンポーネントをアタッチします。プロジェクトビューから「RockPrefab」を選択し、インスペクタのAddComponentをクリックします。
メニューから「Pysics2D」→「Circle Collider2D」を選択します。

f:id:nn_hokuson:20160716072348p:plain:w500

シーンビューのRockPrefabを選択すると、隕石の周りに緑色の円が表示されています。
これが当たり判定のためのCircle Colliderになります。

f:id:nn_hokuson:20160716072755p:plain:w100

弾にはColliderコンポーネントとRigidbodyコンポーネントをアタッチします。
プロジェクトビューから「BulletPrefab」を選択し、インスペクタのAddComponentをクリック、「Pysics2D」→「Circle Collider2D」を選択します。

f:id:nn_hokuson:20160716073211p:plain:w500

続いてRigidbodyコンポーネントをアタッチしましょう。
先ほどと同じように、プロジェクトビューから「BulletPrefab」を選択したうえで、インスペクタのAddComponentから「Pysics2D」→「Rigidbody2D」を選択します。

f:id:nn_hokuson:20160716073859p:plain:w500 


いまアタッチしたCircle Collider 2Dコンポーネントの「Is Trigger」にチェックを入れます。
「Is Trigger」をチェックすると、オブジェクト衝突時に、衝突検知だけをして、衝突オブジェクトはすり抜けるようになります(跳ね返らなくなります)

f:id:nn_hokuson:20170310172903p:plain

また、Rigidbodyコンポーネントの「Is Kinematic」のチェックボックスにチェックを入れます。
「IsKinematic」をチェックすることで、弾は重力などの物理的な力を受けなくなります(このチェックを入れないと、重力で弾は下に落ちていこうとします)

f:id:nn_hokuson:20170310172909p:plain

スクリプトから衝突を検知しよう

スクリプトから、弾と隕石が衝突したことを検知します。
衝突時にはRockControllerかBulletControllerに「OnCollisionEnter2D関数」が実装されていれば、その関数が呼び出されます。

ここではBulletControllerにOnCollisionEnter2Dを付け加えてましょう。
プロジェクトビューからBulletControllerを開いて、次のスクリプトを入力して下さい。

using UnityEngine;
using System.Collections;

public class BulletController : MonoBehaviour {
	void Update () {
		transform.Translate (0, 0.2f, 0);

		if (transform.position.y > 5) {
			Destroy (gameObject);
		}
	}

	void OnTriggerEnter2D(Collider2D coll) {
		Destroy (coll.gameObject);
		Destroy (gameObject);
	}
}


OnTriggerEnter2D関数の中でDestroy関数を使って隕石と弾のオブジェクトを破棄しています。
ゲームを実行して、当たり判定ができているかを確かめてみましょう。

f:id:nn_hokuson:20160716091811g:plain

爆発のエフェクトを追加しよう

隕石を破壊した時に、ただ消えるだけでは寂しいので、爆発のエフェクトを追加します。
Asset Storeに「Toon Explosion VFX Texture Free」という素材があるので、今回はそれを利用します。

f:id:nn_hokuson:20160716092929p:plain
Toon Explosion VFX Texture Free

Unityのツールバーから「Window」→「Asset Store」を選択し、「Toon Explosion VFX Texture Free」を検索してインポートします。
インポートできるとプロジェクトビューにアセットが追加されます。

f:id:nn_hokuson:20160716093810p:plain:w400

このアセットは爆発エフェクトが繰り返し表示される設定になっています。
今回は隕石と弾が衝突した時に一度だけ爆発エフェクトを表示したいので設定を変更します。

プロジェクトビューから「Assets→Textures→Sprites→toonExplotionFree→Example」の中にある「exampleExplosionEffect」を選択し、インスペクタの「Particle System」→「Looping」のチェックを外します。

f:id:nn_hokuson:20160716111234p:plain

隕石と弾が衝突した時にエフェクトを表示したいので、先ほどのOnTriggerEnter2D関数の中に、爆発エフェクトを生成する処理を追加します。

using UnityEngine;
using System.Collections;

public class BulletController : MonoBehaviour {

	public GameObject explosionPrefab;   //爆発エフェクトのPrefab

	void Update () {
		transform.Translate (0, 0.2f, 0);

		if (transform.position.y > 5) {
			Destroy (gameObject);
		}
	}

	void OnTriggerEnter2D(Collider2D coll) {
	        // 爆発エフェクトを生成する	
		Instantiate (explosionPrefab, transform.position, Quaternion.identity);
		Destroy (coll.gameObject);	
		Destroy (gameObject);
	}
}

スクリプト中で宣言したexplosionPrefab変数にPrefabの実体を代入します。
プロジェクトビューから「bulletPrefab」を選択し、インスペクタから「Bullet Controller (Script)」の中にある「Explosion Prefab」の欄を探して下さい。
そこにインポートした爆発エフェクトのPrefabをドラッグ&ドロップします。

f:id:nn_hokuson:20160716104531p:plain:w500

実行して正しく爆発エフェクトをが表示されるかみてみましょう。

f:id:nn_hokuson:20160716110329g:plain

今回はここまでです。今回作成したプロジェクトファイルを置いておきます。

www.dropbox.com

次回は、uGUIを使って得点が表示できるようにUIを作成していきます。

nn-hokuson.hatenablog.com