【Unity】(5分で分かる)Colliderの使い方

Unityでアクションゲームを作るとき、2D,3Dかかわらず必ず必要になるものがあります。
それは当たり判定です。
そして、当たり判定にはCollider(コライダー)というものを使います。
今回はそんなColliderを使って当たり判定を行うにはどうやればいいか解説していきます。
Colliderの概要
Colliderは、当たり判定を行うために使います。
具体的には、Rigidbodyという属性を持ったオブジェクトのColliderに、別オブジェクトのColliderが重なると、スクリプト上でOnCollisionEnterというイベント(一例)が呼ばれるので、それを利用して当たり判定を行います。
※相手のみがRigidbodyを持っている場合もイベントは呼ばれます
図示すると以下です。
Colliderには種類がある
一口にColliderと言っても、実は形状と特性によっていくつか種類があります。
3DであればBox Collider、Capsule Collider、Sphere Collider、2DであればBox Collider 2D、Capsule Collider 2D、Circle Collider 2D等々。


ゲームオブジェクトの形状や役割などを加味して適宜使い分けると良いと思います。
衝突検知の仕方
それではここから実際に当たり判定を実装する方法を見ていきます。
サンプルとして、Unity公式が配布している3Dキャラクターに大砲の砲弾を衝突させ、それを検知(当たり判定)したらエフェクトを使って爆発させる一連の流れを実装してみます。
(※キャラクターを爆破させることについて他意はなく、あくまでこんな実装もゲームとしてあり得るよねという例を紹介させていただいています)
準備編
ここはあまり重要なことは書いていません。実験に使う素材の準備をします。
下記の素材をアセットストアから持ってきます(無料)
- Starter Assets – ThirdPerson(Unity公式のヒューマノイド)
- Stylish Cannon Pack(大砲の3Dモデル)
- Particle Pack(Unity公式のエフェクトセット)

プログラム編
大砲から砲弾を発射させるプログラム
記事の内容とあまり関係ない部分なので、興味のある方は見てみてください。
using System;
using System.Collections;
using UnityEngine;
public class Cannon : MonoBehaviour
{
[SerializeField] private GameObject BulletPrefab;
[SerializeField] private GameObject FireEffectPrefab;
private Rigidbody InstanceBulletRigidbody;
private bool isFire = false;
[SerializeField] private float FirePower = 19.0f;
[SerializeField] private Vector3 FireDirection = new Vector3(-1.0f, 0.3f, 0.0f);
// Update is called once per frame
void Update()
{
if(Input.GetMouseButtonDown(0)&&!isFire){
Fire();
}
}
private void Fire()
{
SetIsFire(true);
Vector3 InitialBulletPosition = transform.position;
InitialBulletPosition.x -= 0.76f;
InitialBulletPosition.y += 0.26f;
Instantiate(FireEffectPrefab, InitialBulletPosition, transform.rotation);
GameObject InstanceBullet=Instantiate(BulletPrefab, InitialBulletPosition, transform.rotation);
InstanceBulletRigidbody = InstanceBullet.GetComponent<Rigidbody>();
InstanceBulletRigidbody.AddForce(FireDirection*FirePower,ForceMode.Impulse);
StartCoroutine(DelayMethod(1.0f,()=>SetIsFire(false)));
}
private void SetIsFire(bool value)
{
isFire = value;
}
private IEnumerator DelayMethod(float waitTime,Action action)
{
yield return new WaitForSeconds(waitTime);
action();
}
}
大雑把にやっていることを説明すると、
- マウスクリックされると発動
- 砲弾のPrefab(後ほど作成)を生成
- 大砲発射エフェクトのprefabもついでに生成
ということをやってます。
砲弾自体のプログラム
このプログラムが今回の記事の肝で、当たり判定を実際にやっています。
using UnityEngine;
public class Bullet : MonoBehaviour
{
[SerializeField] private GameObject ExplosionPrefab;
void OnCollisionEnter(Collision collision)
{
Vector3 ExplosionPosition = transform.position;
Instantiate(ExplosionPrefab, ExplosionPosition, transform.rotation);
Destroy(collision.gameObject);
Destroy(gameObject);
}
}
解説します。
void OnCollisionEnter(Collision collision)
→Colliderに他のオブジェクトのColliderが接触したときに呼び出されるイベントです。
Vector3 ExplosionPosition = transform.position;
Instantiate(ExplosionPrefab, ExplosionPosition, transform.rotation);
→砲弾自身と同じ位置に爆破エフェクトを生成します。
Destroy(collision.gameObject);
→イベントの引数のcollisionは、衝突した相手オブジェクトの情報を持っています。
collision.gameObjectとすることで、相手オブジェクトにダイレクトにアクセスできるため、Destroyによって爆破と同時にシーン上から削除しています。
Destroy(gameObject);
→最後に砲弾自身もシーン上から消して綺麗さっぱり証拠隠滅完了です。
インスペクター編
それでは、シーンに移ります。
まずはこのように大砲とヒューマノイドを配置しました。

大砲には大砲スクリプト(Cannonと命名しています)をアタッチしています。
次に、ヒエラルキーから+→3D Object→Sphereを作成しサイズを変更します。

そして、Rigidbodyを追加し、砲弾スクリプト(Bulletと命名しています)をアタッチします。
このとき、このオブジェクトの砲弾スクリプトをインスペクターから見ると、ExplosionPrefabという項目があると思いますので、Particle Pack に含まれているBigExplosionというエフェクトのprefabを当てはめます。

今作ったオブジェクトが砲弾となりますので、Prefab化しておきます。
そしたら、大砲オブジェクトのインスペクターを見てみましょう。
その中の大砲スクリプトにBulletPrefabとFireEffectPrefabの項目があることが確認できると思います。

BulletPrefabに先ほど作った砲弾のPrefabを当てはめます。
FireEffectPrefabにはParticle Pack に含まれているDustExplosionというエフェクトのprefabを当てはめます。
※エフェクトについては、全ParticleSystemの(子オブジェクトも含めて)Loopingのチェックを外し、おなじく全ParticleSystem のStopActionをDestroyに設定しています)
ここまでできたら一通り完了です。
それではゲーム画面で確認してみましょう。
動画のように、大砲から発射された砲弾がヒューマノイドにあたった瞬間盛大に爆破していることがわかるかと思います。
これが当たり判定です。
アクションゲームの基本のキ
アクションゲームをつくるなら、Colliderを使った当たり判定は基本中の基本となります。
ぜひ今回の内容をしっかりと押さえて、アクションゲームの開発にもチャレンジしていただければと思います。