ひとりでのアプリ開発 - fineの備忘録 -

ひとりでアプリ開発をするなかで起こったことや学んだことを書き溜めていきます

Unity入門 - 当たり判定、Collider、Collision -

初めに



 オブジェクトが何かに接触した際、当たり判定を取得する方法をまとめます。

当たり判定の取得に必要なもの

 当たり判定を取得するするには、次の2つが必要になります。

  1. Rigidbody
  2. Collider

 Rigidbodyの付け方については、以前、記事をまとめましたので、そちらをご覧ください。
fineworks-fine.hatenablog.com

Colliderをアタッチする

 基本的には、3dオブジェクトには初めからColliderがアタッチされています。
 例えば、Sphereを生成すると、Sphere Colliderがついていることがわかります。

 初めから、ColliderがついていないオブジェクトにColliderをつけるには、インスペクターのAddComponentから付けることができます。
 AddComponent→Physics もしくは AddComponent→colliderで検索をすれば、いろいろなBox ColliderやCircle ColliderなどさまざまなColliderがあることがわかります。形の合うものを選んで、アタッチしましょう。

名前 説明
Box Collider 直方体
Capsule Collider カプセル型
Sphere Collider
Mesh Collider モデルの見た目そのままでの当たり判定を取ることができる
Wheel Collider 車のタイヤ型。Colliderでありながら、質量や進行方向への摩擦などと、物理的なパラメータが含まれる
Terrain Collider 地形用Collider

当たり判定を取得する

 次の手順で取得することができます。


  1. オブジェクトにRigidbody, Colliderをアタッチする
  2. 当たり判定の取得に使われる関数をスクリプトに記述、アタッチする

当たり判定の取得に使われる関数

 次の3つの関数を使われます。

関数 呼び出されるタイミング
OnCollisionEnter 他のcollider/rigidbodyに触れた時
OnCollisionStay 他のcollider/rigidbodyに触れている間、毎フレーム1度だけ呼び出される
OnCollisionExit 他のcollider/rigidbodyから離れた時

実際に当たり判定を取得してみる

 Rigidbody、Colliderと次のスクリプトSphereにアタッチします・

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

public class SphereScript : MonoBehaviour
{
    //他のcollider/rigidbodyに触れたときに呼び出される
    void OnCollisionEnter(Collision collision)
    {
        Debug.Log("何かに当たったにぇ"); // ログを表示する
    }
}

 また、Cube(Box Colliderがアタッチされている)を生成し、サイズ、位置を調整してから、実行してみます。

Colliderの引数:Collsion

 先ほどのスクリプトを見ると、呼び出される関数に引数があることが分かります。

    //他のcollider/rigidbodyに触れたときに呼び出される
    //collisionという名前でCollisionが引数として得られる
    void OnCollisionEnter(Collision collision)  
    {
        Debug.Log("何かに当たったにぇ"); // ログを表示する
    }

 Collisionから、衝突したオブジェクトの情報を扱うことができます。例えば、次のようにスクリプトを変えてみると、Debug.Logには衝突したオブジェクトの名前が表示されます。

    //他のcollider/rigidbodyに触れたときに呼び出される
    //collisionという名前でCollisionが引数として得られる
    void OnCollisionEnter(Collision collision)  
    {
        Debug.Log("collision.gameObject.name"); // ログに衝突したオブジェクトの名前を表示する
    }

衝突させずに関数だけ呼び出す場合

 ColliderのIsTriggerにチェックを入れます。

 すると、Rigidbodyがある状態でオブジェクトをすり抜けることが可能になります。しかし、コンソールにDebug.Logが現れていません。

 関数が呼び出されなかった理由は、IsTriggerにチェックをした場合、呼び出される関数OnCollision関数ではないからです。この場合、呼び出されるのはmOnCollisionではなく、OnTrigger関数である次の3つになります。

関数 呼び出されるタイミング
OnTriggerEnter 他のcollider/rigidbodyに触れた時
OnTriggerStay 他のcollider/rigidbodyに触れている間、毎フレーム1度だけ呼び出される
OnTriggerExit 他のcollider/rigidbodyから離れた時

IsTrigger関数の書き方

 OnCollision関数との違いは2つあります。

  1. Collisionの部分がTriggerになったこと
  2. 引数がCollisionではなくColliderになったこと

 スクリプトを見てみましょう。

void OnTriggerEnter(Collider t)  //ここが変化
    {
        Debug.Log(t.gameObject.name); // ログを表示する
    }

最後に

 当たり判定の取得の仕方をまとめました。初めて当たり判定を取得する場合は、一つひとつ確認しながらやりましょう。処理が複雑のため、一回分からなくなると初めからやり直すことになります。