【2Dシューティング】Unity公式チュートリアルをやってみる4回目。当たり判定。

こんにちは。【2Dシューティング】Unity公式チュートリアルをやってみるシリーズの4回目です。前回は敵の作成でした。
【2Dシューティング】Unity公式チュートリアルをやってみる3回目。敵の作成

今回は当たり判定の実装です。めんどくさいですがやっていこうと思います

当たり判定を実装していこう

ここでやること

  • 自機、敵、弾にcolliderを追加。
  • 当たり判定の実装
  • SpaceShipScriptに爆発Prefab用コードを追加
  • SpaceShipScriptに爆発Prefabをアタッチ。&調整
  • 爆発エフェクトを消すためのスクリプトを作成
  • 爆発Prefabに爆発エフェクトを消すためのスクリプトをアタッチ

colliderってなんだよってなると思いますが、Unityの当たり判定にcolliderが必ず必要になります。rigidbodyも必要になりますが、rigidbodyに関してはすでに追加済みです。colliderはadd componentから追加できます。

colliderを追加しよう

colliderは当たり判定するための「範囲」みたいなもんで色々あります。公式チュートリアルがクソすぎるので、どのオブジェクトにどのcolliderを追加するのかを表にまとめます。

自機 BoxCollider2D is Triggerにチェック
自機の弾(※PlayerBulletの子要素の弾に追加します※) Polygon Collider2D is Triggerにチェック
Polygon Collider2D is Triggerにチェック
敵の弾(EnemyBullet) CircleCollider2D is Triggerにチェック

画像にしたいところですが、めんどくさすぎるので、ただadd componentで追加していくだけすし、colliderの調整に関してもはぶきます。当たり判定の範囲を変えたかったらあとから変えればいいだけのこと。

当たり判定のコードを書こう

当たり判定はOnTriggerEnter2Dとい関数を使って実装します。決まり文句みたいなもんなのでコピペ推奨です。

//ぶつかった瞬間よびだされる
void OnTriggerEnter2D (Collider2D c){
  Destroy(c.gameObject);//弾の削除
  spaceship.Explosion();//爆発する
  Destroy(gameObject);//プレイヤーの削除
}

プレイヤーに弾があたったら爆発させよう

SpaceShipScriptに爆発Prefab用のコードを追加します。

// 爆発のPrefab
public GameObject explosion;

// 爆発の作成
public void Explosion ()
{
  Instantiate (explosion, transform.position, transform.rotation);
}

このコードを追加すると爆発Prefabをアタッチできるようになるのでアタッチします。
screenshot 20181213 0009
これで死んだら爆発するが、爆発アニメがその場にのこりつづけるのでそれを改善する。前々回記事あたりで爆発アニメーションを作ったが、爆発アニメーションのLoopチェックをはずす。
screenshot 20181213 0014
やってみればわかるがループはしなくなるもののエフェクトが画面にのこりつづけている。これを改善する。公式チュートリアルではえらくまわりくどいことをしているので別のやり方でやる。

爆発Prefabを消すためのスクリプトを書いてやりそれを爆発Prefabにアタッチする。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ExplosionScript : MonoBehaviour {

	void Start () {
		Destroy(gameObject, 0.5f);//インスタンスが生成されて0.5秒後に消す
	}
}

このスクリプトを保存して爆発Prefabにアタッチする。
screenshot 20181213 0025

敵の当たり判定に関しては触れてないが、まったく同じコードをEnemyScriptに追加すれば、いいだけなので省略する。

レイヤーの設定

ここまで作業をすすめると自機はともかくとして敵は100%自爆するようになっている。これは自分が撃った弾にあたってしまうためだ、(弾を撃った瞬間OnTriggerEnter2Dがよばれてしぬ)これを防ぐためにLayerを設定する。

レイヤーを最初理解するのはめんどうだが以外に簡単だ。右の表はチェックが外れていれば当たり判定は無視される。この表の名前はなにを表しているのかというとレイヤーだ。最初からレイヤーが用意されているのでそれを決めるだけだ。
screenshot 20181213 0114

敵オブジェクトにはEnemyレイヤー、敵の弾オブジェクトにはBullet(Enemy)レイヤーを設定してやれば、表の組み合わせが適用され、当たり判定が無視され、自爆がおこらなくなる。

画面外に出たら弾を消そう

ここでやること

  • 空のオブジェクトを作成。名前はDestroyAreaにする
  • DestroyAreaにbox collider2Dを追加
  • DestroyArea用Scriptを作成→アタッチ

空のオブジェクトを作ってcolliderを追加しよう

空のオブジェクトを作って名前はDestroyAreaに。box colliderを追加してis Triggerにチェックを入れる。なにをしたいかというとcolliderからオブジェクトがはみでたら消すという処理をする。

Edit Colliderを使いColliderの範囲を調整しよう。ちなみにEdit Colliderはhierarkhyにあるオブジェクトでしか使うことができない。Edit Colliderを選択するとSceneViewに緑色の線がでてくるのでそれが「範囲」だ。これを適当にドラッグ&ドロップしてやると範囲を調整できる。
screenshot 20181213 0136

DestroyAreaScirptをつくろう

さっき範囲を作成したので、この範囲から出たらオブジェクトを消すようにする。これを実現するのがOnTriggerExit2D関数だ。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestroyAreaScript : MonoBehaviour {
	void OnTriggerExit2D(Collider2D c){
		Destroy(c.gameObject);
	}
}

このスクリプトを作ったらDestroyAreaオブジェクトにアタッチしよう。

再生すると自機と敵が爆発してしまう・・・

これはなぜかというと自機がDestroyAreaにいると自機スクリプトで実装したOnTriggerEneter2D関数が呼び出されてしまうためだ。これを解決するには、前のほうで触れた、レイヤーを設定する必要がある。前のほうでみたLayer Collision Matrixの表をみて必要ないチェックははずす。これで当たり判定が無視され自機が爆発することはなくなる。

ここまでの状態

クソだるい。けどなんとか思った通りの動きに。
screenshot-201812130204

次の記事

この記事の作業で困った現象に下記のようなものがありましたので参考まで。
Unityでレイヤーを変更するとオブジェクトが消えてしまう原因

次の記事は背景の作成とスクロールの実装です。
【2Dシューティング】Unity公式チュートリアルをやってみる5回目。背景をつくる。