見出し画像

Unityのイベント関数③ | OnCollision系,OnTrigger系 衝突侵入判定を徹底解説

イベント関数の記事1回目

  • Update

  • FixedUpdate

  • LateUpdate

そしてイベント関数の記事2回目では以下のイベント関数について解説しました。

  • Awake

  • OnEnable

  • Start

今回は、ゲーム作りでよく使う当たり判定のイベント関数、
OnCollision系とOnTrigger系について解説します。

アイテムを取ったとき、敵にぶつかったとき、ゴールに入ったときなど、ゲームでは「何かに触れたとき」の処理がたくさん出てきます。

そのようなときに使うのが、今回のイベント関数です。



OnCollisionとOnTriggerとは

どちらも、オブジェクト同士が触れたときに自動で呼ばれるイベント関数です。

ただし、同じ「触れる」でも役割が少し違います。

OnCollision

物理的にぶつかる当たり判定

OnTrigger

すり抜ける当たり判定

たとえば、

  • 壁にぶつかる

  • 地面に着地する

このような「実際にぶつかる」処理は OnCollision

  • アイテムを取る

  • ゴールに入る

  • 敵の警戒範囲に入る

このような「重なったことを判定したいだけ」の処理は OnTrigger と考えると分かりやすいです。


まずは一覧

OnCollision系

void OnCollisionEnter2D(Collision2D collision)
{
}

void OnCollisionStay2D(Collision2D collision)
{
}

void OnCollisionExit2D(Collision2D collision)
{
}

OnTrigger系

void OnTriggerEnter2D(Collider2D other)
{
}

void OnTriggerStay2D(Collider2D other)
{
}

void OnTriggerExit2D(Collider2D other)
{
}

今回は、2Dゲームでよく使う 2D版 を中心に説明します。


OnCollision 系関数の意味

OnCollisionEnter2D

ぶつかった瞬間に1回だけ呼ばれます。

void OnCollisionEnter2D(Collision2D collision)
{
    Debug.Log("何かにぶつかりました");
}

たとえば、

  • 地面に着地した瞬間

  • 敵にぶつかった瞬間

  • 壁に当たった瞬間

などに使えます。


OnCollisionStay2D

ぶつかっている間、呼ばれ続けます。

void OnCollisionStay2D(Collision2D collision)
{
    Debug.Log("ぶつかっている最中です");
}

ずっと接触している間に何かをしたいときに使います。

ただし、物理演算の更新ごとに呼ばれ続けます。重い処理をたくさん書かないように注意しましょう。


OnCollisionExit2D

ぶつかっていたものから離れた瞬間に呼ばれます。

void OnCollisionExit2D(Collision2D collision)
{
    Debug.Log("ぶつかりが終わりました");
}

たとえば、

  • 地面から離れてジャンプした瞬間

  • 壁から離れた瞬間

などの判定に使えます。


OnTrigger系関数の意味

OnTriggerEnter2D

Triggerの範囲に入った瞬間に呼ばれます。

void OnTriggerEnter2D(Collider2D other)
{
    Debug.Log("Triggerに入りました");
}

たとえば、

  • コインを取った

  • ゴールに入った

  • 回復エリアに入った

などに向いています。


OnTriggerStay2D

Triggerの中にいる間、呼ばれ続けます。

void OnTriggerStay2D(Collider2D other)
{
    Debug.Log("Triggerの中にいます");
}

たとえば、

  • ダメージゾーンにいる間、少しずつHPを減らす

  • 回復ゾーンにいる間、少しずつ回復する

などに使えます。


OnTriggerExit2D

Triggerの範囲から出た瞬間に呼ばれます。

void OnTriggerExit2D(Collider2D other)
{
    Debug.Log("Triggerから出ました");
}

たとえば、

  • セーフエリアから出た

  • 敵の見つける範囲から出た

などの判定に使えます。


OnCollisionとOnTriggerの違い

違いをシンプルにまとめると、次のようになります。

つまり、

ぶつかって止まるならCollision
重なったことだけ判定したいならTrigger

と覚えると分かりやすいです。


Triggerを使うには Is Trigger をONにする

OnTrigger を使いたい場合は、Collider の Is Trigger にチェックを入れる必要があります。

逆に、OnCollision を使う場合は、通常は Is Trigger をOFF にして使います。

まとめると

  • Is Trigger OFF → OnCollision

  • Is Trigger ON → OnTrigger

です。


実際の使用例1 コインを取る

たとえば、プレイヤーがコインに触れたら、コインを取ったことにして消す処理を作ってみます。

このような処理では、OnTriggerEnter2D をよく使います。

using UnityEngine;

public class Coin : MonoBehaviour
{
    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            Debug.Log("コインを取りました");
            Destroy(gameObject);
        }
    }
}

このコードでは、プレイヤーがコインに重なった瞬間に、

  • 「コインを取りました」と表示する

  • コインを消す

という処理をしています。

コインは、プレイヤーと物理的にぶつかって止まる必要はありません。
プレイヤーが重なったことだけ分かればよいので、Trigger向きです。


Collider2D other の other とは?

ここで少し分かりにくいのが、この部分です。

void OnTriggerEnter2D(Collider2D other)

other は、Trigger に入ってきた相手の情報を受け取るための名前です。

たとえば、プレイヤーがコインに触れた場合、
その「触れてきた相手」であるプレイヤーの Collider2D の情報が other に入ります。

そして、次の行で使っている other も、上で受け取った同じものです。

if (other.CompareTag("Player"))

つまり、

Collider2D other

の other と、

other.CompareTag("Player")

の other は、同じものです。

「Triggerに入ってきた相手を other という名前で受け取って、その相手が Player かどうかを調べている」

と考えると分かりやすいです。


other という名前は変えてもいい

実は、other という名前は自分で付けている名前です。

なので、次のように collision という名前にしても動きます。

void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.CompareTag("Player"))
    {
        Debug.Log("コインを取りました");
        Destroy(gameObject);
    }
}

この場合も、

Collider2D collision

の collision と、

collision.CompareTag("Player")

の collision は同じものです。

ただし、OnTriggerEnter2D の引数は Collision2D ではなく Collider2D です。

そのため、初心者のうちは collision よりも、
「相手」という意味の other を使った方が分かりやすいと思います。


1行ずつ見てみよう

もう一度、コードを1行ずつ見てみます。

using UnityEngine;

Unityの機能を使うために必要な一文です。


public class Coin : MonoBehaviour

Coin というスクリプトを作っています。

このスクリプトは、コインのオブジェクトに付ける想定です。


void OnTriggerEnter2D(Collider2D other)

何かがこのオブジェクトの Trigger に入った瞬間に、自動で呼ばれるイベント関数です。

other には、Trigger に入ってきた相手の情報が入ります。


if (other.CompareTag("Player"))

Trigger に入ってきた相手のタグが Player かどうかを調べています。

つまり、

「触れてきた相手はプレイヤーですか?」

と確認しています。


Debug.Log("コインを取りました");

Console に「コインを取りました」と表示します。

実際のゲームでは、ここにスコアを増やす処理や効果音を鳴らす処理を追加することもできます。


Destroy(gameObject);

このスクリプトが付いているオブジェクトを削除します。

今回の場合、Coin スクリプトをコインに付けているので、
gameObject はコイン自身を表します。

つまり、この行でコインが消えます。


実際の使用例2 敵にぶつかったらダメージ

敵にぶつかったときにダメージを受ける処理を作る場合は、OnCollisionEnter2D を使うことがあります。

using UnityEngine;

public class PlayerDamage : MonoBehaviour
{
    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Enemy"))
        {
            Debug.Log("敵にぶつかってダメージ");
        }
    }
}

この例では、敵と物理的にぶつかった瞬間に、ダメージ処理を行う想定です。


Collision2D collision の collision とは?

OnCollisionEnter2D では、引数の型が Collision2D になります。

void OnCollisionEnter2D(Collision2D collision)

この collision には、ぶつかった相手との接触情報が入ります。

OnTriggerEnter2D のときは、

Collider2D other

でした。

一方、OnCollisionEnter2D では、

Collision2D collision

になります。

Collision2D には、ぶつかった相手の情報だけでなく、接触した位置など、衝突に関する情報も含まれます。

そのため、相手の GameObject を調べるときは、次のように書きます。

collision.gameObject.CompareTag("Enemy")

これは、

「ぶつかった相手の GameObject のタグは Enemy ですか?」

という意味です。


1行ずつ見てみよう

public class PlayerDamage : MonoBehaviour

PlayerDamage というスクリプトを作っています。

このスクリプトは、プレイヤーに付ける想定です。


void OnCollisionEnter2D(Collision2D collision)

何かと物理的にぶつかった瞬間に、自動で呼ばれるイベント関数です。

collision には、ぶつかった相手との接触情報が入ります。


if (collision.gameObject.CompareTag("Enemy"))

ぶつかった相手のタグが Enemy かどうかを調べています。

つまり、

「ぶつかった相手は敵ですか?」

と確認しています。


Debug.Log("敵にぶつかってダメージ");

Console に「敵にぶつかってダメージ」と表示します。

実際のゲームでは、ここにHPを減らす処理などを追加します。


実際の使用例3 ゴールに入ったらクリア

ゴール判定も、OnTriggerEnter2D を使うことが多いです。

using UnityEngine;

public class Goal : MonoBehaviour
{
    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            Debug.Log("ゲームクリア");
        }
    }
}

ゴールは、プレイヤーが重なればOKです。
壁のようにぶつかって止まる必要はありません。

そのため、ゴール判定も Trigger向き です。


このコードの考え方

void OnTriggerEnter2D(Collider2D other)

ここで、ゴールの範囲に入ってきた相手を other として受け取ります。

そして、

if (other.CompareTag("Player"))

で、その相手がプレイヤーかどうかを調べています。

プレイヤーだった場合だけ、

Debug.Log("ゲームクリア");

を実行します。

つまり、

ゴールに入ってきた相手がプレイヤーなら、ゲームクリアにする

という処理です。


other と collision の違い

ここまでで、

Collider2D other

Collision2D collision

の2つが出てきました。

少しややこしく見えますが、最初は次のように考えると分かりやすいです。

OnTriggerEnter2D では、

Collider2D other

を使います。 (othre はただの引数なので、名前を変えてもいいですよ)

これは、Trigger に入ってきた相手の Collider 情報です。

一方、OnCollisionEnter2D では、

Collision2D collision

を使います。

これは、実際にぶつかったときの衝突情報です。

簡単にまとめると、

Trigger は Collider2D
Collision は Collision2D

です。


2Dと3Dの違いに注意

今回紹介したのは 2D用 です。

2Dと3Dでは、関数名や引数が少し変わります。

2Dの場合

void OnCollisionEnter2D(Collision2D collision)
{
}

void OnTriggerEnter2D(Collider2D other)
{
}

3Dの場合

void OnCollisionEnter(Collision collision)
{
}

void OnTriggerEnter(Collider other)
{
}

2Dの場合は、関数名や型の最後に 2D が付きます。

3Dの場合は、2D が付きません。


まとめ

今回は、当たり判定で使うイベント関数、

  • OnCollision

  • OnTrigger

について解説しました。

ポイントをまとめると、次の通りです。

  • OnCollision は、物理的にぶつかる当たり判定

  • OnTrigger は、すり抜ける当たり判定

  • OnTriggerEnter2D では Collider2D other を使う

  • OnCollisionEnter2D では Collision2D collision を使う

  • other.CompareTag("Player") は、入ってきた相手が Player かどうかを調べている

  • collision.gameObject.CompareTag("Enemy") は、ぶつかった相手が Enemy かどうかを調べている

  • 2Dでは関数名や型の最後に 2D が付く

  • OnTrigger を使うときは、Collider2D の Is Trigger をONにする

当たり判定は、ゲーム作りでとてもよく使います。

アイテム取得、敵との接触、ゴール判定など、たくさんの場面で出てくるので、実際にコードを書きながら覚えていきましょう。


Unity初心者向けの記事をテーマ別にまとめています。

▼ Unity初心者向け記事まとめはこちら


こちらのマガジン「ミニゲーム作成講座 全8回セット」でもシーンの切り替えなどを活用して、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。

さらにステップアップの「スマホで遊ぶジャンプゲーム 8回セット」のマガジンもぜひご活用ください。


ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。

ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

いいなと思ったら応援しよう!

ファイブボックス よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!