[unity]初心者でもわかる、Collider の使い方

Unity の Collider は分かりやすく出来ている……のですが、それでもしらばく使っていないと「あれ、どうだったっけ……」、となりがち。

ここでは一番簡単な使い方と、特に気を付けるべき点についてまとめました。

大事なポイント

Collider を一度も使った事のない人が、知っておくべきポイントは2つです。

Collider は「物理演算」と「衝突制御」の2つの役割がある

物理演算とは、物体が落ちたり、自動的に跳ねたりする挙動のこと。
衝突判定とは、物体Aと物体Bが触れ合ったことをスクリプトで確認することです。

Collider は「物理演算+衝突判定」と「衝突判定のみ」を選択できますが、それぞれで呼び出されるコールバック関数は別になっており、間違えると「コールバックが動作しない……」と悩む原因になります。

その問題については「注意:実行されるコールバック関数が違う」の項をご覧ください。

2D と 3D で別の Collider がある

実は 2D 用にも Collider が用意されています。コールバック関数も 2D 用になります。
当然間違えるとコールバック動作しない症候群に悩まされるので、気をつけましょう。

2D オブジェクトにも 3D Collider を使うことはできますが、処理は 2D より重くなるので、余程の理由がない限り 2D Collider を使いましょう。

3D のサンプル(物理演算あり)

OnTrigger~ と OnCollision~ は同時に動くことはありませんが、サンプルなので同じスクリプトにまとめました。

CollisionTest.cs

using TMPro;
using UnityEngine;

public class CubeColliderTest : MonoBehaviour
{
    /// <summary>
    /// IsTrigger = true の時のコールバック関数
    /// </summary>
    void OnTriggerEnter(Collider other)
    {
        Debug.Log($"TriggerEnter: {other.name}");
    }

    void OnTriggerStay(Collider other)
    {
        Debug.Log($"TriggerStay: {other.name}");
    }

    void OnTriggerExit(Collider other)
    {
        Debug.Log($"TriggerExit: {other.name}");
    }

    /// <summary>
    /// IsTrigger = false の時のコールバック関数
    /// </summary>
    void OnCollisionEnter(Collision other)
    {
        Debug.Log($"CollisionEnter: {other.collider.name}");
    }

    void OnCollisionStay(Collision other)
    {
        Debug.Log($"CollisionStay: {other.collider.name}");
    }

    void OnCollisionExit(Collision other)
    {
        Debug.Log($"CollisionExit: {other.collider.name}");
    }
}

シーンには1つの立方体(Cube)と球(Sphere)を配置します。

Cube

BoxCollider は最初からついています。CubeColliderTest は先ほどのコードをアタッチしてください。

接触判定には必ずどちらかのオブジェクトに Rigidbody が必要ですが、大抵動くオブジェクトにつけておけばOKです。
今回は球の方につけることにします。Cube は動かない床なので Rigidbody はつけません。

Sphere

こちらには Rigidbody を追加でアタッチしてください。
Use Gravity に✓がついていると自動的に重力のかかった動作になります。
(スクリプトを使って、自分で球を動かす場合は✓を外すこともあります)

実行

ボールが落下し、縁に一旦接触した後落ちるようにしたところ、ログには次のように表示されました。

CollisionEnter が接触開始、CollisionStay が接触中、CollisionExit が接触終了のタイミングです。

CollisionStay は接触している間、一定の間隔で呼び出され続けます。
ただし、接触中永遠に Stay が呼び出されると処理が重くなってしまうので、Unity は画面に新たな変化がないまま一定時間経過すると Stay を呼ばなくなる(サボる)ので注意してください。

この「一定時間」は Project Settings > Physics2D > Time to Sleep の値を変更することで増減が可能です。

3D のサンプル(物理演算なし)

変更点は1か所だけ

先ほどと同じままで、Sphere か Cube 両方の Is Trigger に✓をつけると物理演算がオフになります。

実行

球は地面に接触しても跳ね返ることなく、めり込んだまま落下します。

めり込んでいる間はずっと Stay なので、先ほどよりログも長くなっています。
(この Stay が多すぎる場合、先ほどの Time to Sleep で調整できるというわけです)

【注意!】実行されるコールバック関数が違う

このログに注意してほしいのですが、物理演算ありでは次のように表示されていました。

Collision~: Sphere

今回の物理演算なしでは次のように表示されています。

Trigger~: Sphere

物理演算を切り替えると、呼び出されるコールバックが変化する、ということです。
また、コールバック関数が違うだけではなく、引数も異なっているので更に注意が必要です。

void OnTriggerEnter(Collider other)
void OnCollisionEnter(Collision other)

Collider Collision はいかにも間違えてしまいそうですが、間違えてもエラーにはならず、ただコールバックが実行されないだけなので、注意深く合わせる必要があります

初めて Collider を使う人の多くが「とても」陥りやすい罠なので、気を付けてください。

2D の場合

3D との相違点のみ挙げておきます。

~2D という名前の Collider を使う

そのまま 3D 用の Collider を使うことも可能ですが、処理の重さを考えるのであれば 2D 系の Collider を使いましょう。(BoxCollider2DCircleCollider2DRigidBody2D など)

RigidBody2D には RigidBody になかった重力係数があったり、微妙にパラメーターが異なっています。

Collider は自分でアタッチする

多くの場合は BoxCollider2DCircleCollider2D で事足りると思います。
その他、接触するオブジェクトのどちらかに RigidBody2D をつける事も忘れずに。

コールバック関数もすべて 2D をつける

これも間違えないようにしましょう。2D を付け忘れると接触イベントを拾うことができません。
IsTrigger の有無でイベントが変化するところは 3D 同様です。

void OnTriggerEnter2D(Collider2D other)
void OnTriggerStay2D(Collider2D other)
void OnTriggerExit2D(Collider2D other)

void OnCollisionEnter2D(Collision2D other)
void OnCollisionStay2D(Collision2D other)
void OnCollisionExit2D(Collision2D other)

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA