26
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

[Unity] 衝突判定における、IsTriggerとRigidbodyとIsKinematicのパターンを実験

目的

IsTrigger」「Rigidbody」「IsKinematic」の有無による挙動の変化を、細かく理解する

したこと

前提

オブジェクト2つ「A (0,0,0)」「B (-3,0,0)」を用意し、Aを動かして、停止しているBにぶつける

試したパターン

【 Aの移動方法 】
・ transform.positionの増減: transform.position -= transform.right * speed * Time.deltaTime
・ Rigidbodyのvelocity: GetComponent<Rigidbody>().velocity = transform.right * speed

【 AのIsTrigger 】
オン / オフ

【 BのIsTrigger 】
オン / オフ

【 AのRigidbody 】
有り(+IsKinematic) / 有り / 無し

【 BのRigidbody 】
有り(+IsKinematic) / 有り / 無し

スクリプト

Aobject.cs
public class Aobject : MonoBehaviour {

    void Update () {
        const int speed = 3; 
        // 左に移動して、Bobjectに衝突させる 
        // 以下2通りの移動方法を切り替えて実験!
        transform.position -= transform.right * speed * Time.deltaTime;
        //GetComponent<Rigidbody>().velocity = transform.right * speed;
    }

    const string NAME = "A";
    const string OPPONENT = "Bobject";

    void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.tag == OPPONENT)
        {
            Debug.Log(NAME + ": OnCollisionEnter");
        }
    }

    void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.tag == OPPONENT)
        {
            Debug.Log(NAME + ": OnTriggerEnter");
        }
    }
}
Bobject.cs
public class Bobject : MonoBehaviour {

    const string NAME = "B";
    const string OPPONENT = "Aobject";

    void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.tag == OPPONENT)
        {
            Debug.Log(NAME + ": OnCollisionEnter");
        }
    }

    void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.tag == OPPONENT)
        {
            Debug.Log(NAME + ": OnTriggerEnter");
        }
    }
}

☆まとめ☆

  • Collisionイベントは、Triggerがともにオフで、かつ動いている側がRigidbodyの場合に発火する
  • 非物理移動のtransform.positionによる移動で発生するCollisionでは、衝突される側がRigidbodyかつIsKinematicがオフでなければ、移動が阻害されて止まってしまう(震えて膠着するように見える)
  • 物理移動のvelocityによる移動で発生するCollisionでは、衝突される側がRigidbodyかつIsKinematicオフでなければ、移動が停止する。
  • Triggerイベントは、Rigidbodyをどちらかにつければ発火する
  • Triggerイベントは、IsTriggerをどちらかにつければ、両方とものオブジェクトで発火する
  • Triggerイベントは、衝突された側が先に発火する。ただし、片方にしかTriggerがついていない場合は、ついている方から発火する

実験結果

上記結論に至った、実験の詳細。

Aを「transform.positionの増減」で移動する場合

AのTrigger BのTrigger AのRigidbody BのRigidbody 発火イベント
オン オン 有り(+IsKinematic) 有り(+IsKinematic) BのTrigger、AのTrigger。通過。
オン オン 有り(+IsKinematic) 有り BのTrigger、AのTrigger。通過。
オン オン 有り(+IsKinematic) 無し BのTrigger、AのTrigger。通過。
オン オン 有り 有り(+IsKinematic) BのTrigger、AのTrigger。通過。
オン オン 有り 有り BのTrigger、AのTrigger。通過。
オン オン 有り 無し BのTrigger、AのTrigger。通過。
オン オン 無し 有り(+IsKinematic) BのTrigger、AのTrigger。通過。
オン オン 無し 有り BのTrigger、AのTrigger。通過。
オン オン 無し 無し 何も起きない
オン オフ 有り(+IsKinematic) 有り(+IsKinematic) AのTrigger、BのTrigger。通過。
オン オフ 有り(+IsKinematic) 有り AのTrigger、BのTrigger。通過。
オン オフ 有り(+IsKinematic) 無し AのTrigger、BのTrigger。通過。
オン オフ 有り 有り(+IsKinematic) AのTrigger、BのTrigger。通過。
オン オフ 有り 有り AのTrigger、BのTrigger。通過。
オン オフ 有り 無し AのTrigger、BのTrigger。通過。
オン オフ 無し 有り(+IsKinematic) AのTrigger、BのTrigger。通過。
オン オフ 無し 有り AのTrigger、BのTrigger。通過。
オン オフ 無し 無し 何も起きない
オフ オン 有り(+IsKinematic) 有り(+IsKinematic) BのTrigger、AのTrigger。通過。
オフ オン 有り(+IsKinematic) 有り BのTrigger、AのTrigger。通過。
オフ オン 有り(+IsKinematic) 無し BのTrigger、AのTrigger。通過。
オフ オン 有り 有り(+IsKinematic) BのTrigger、AのTrigger。通過。
オフ オン 有り 有り BのTrigger、AのTrigger。通過。
オフ オン 有り 無し BのTrigger、AのTrigger。通過。
オフ オン 無し 有り(+IsKinematic) BのTrigger、AのTrigger。通過。
オフ オン 無し 有り BのTrigger、AのTrigger。通過。
オフ オン 無し 無し 何も起きない
オフ オフ 有り(+IsKinematic) 有り(+IsKinematic) 何も起きない
オフ オフ 有り(+IsKinematic) 有り AのCollison、BのCollision。A,Bともに左に移動していく。
オフ オフ 有り(+IsKinematic) 無し 何も起きない
オフ オフ 有り 有り(+IsKinematic) AのCollison、BのCollision。A,Bはその場で震えて?膠着。
オフ オフ 有り 有り AのCollison、BのCollision。A,Bともに左に移動していく。
オフ オフ 有り 無し AのCollison、BのCollision。A,Bはその場で震えて?膠着。
オフ オフ 無し 有り(+IsKinematic) 何も起きない
オフ オフ 無し 有り 何も起きない
オフ オフ 無し 無し 何も起きない

Aを「Rigidbodyのvelocity」で移動する場合

velocityによる移動は物理演算を伴うので、AにはRigidbodyが必須である。
また、IsKinematicがオン(=物理演算無効状態)だと、velocityによる移動は不可になり、Aが動かなくなるのでそのパターンは省略する。

AのTrigger BのTrigger AのRigidbody BのRigidbody 結果
オン オン 有り 有り(+IsKinematic) BのTrigger、AのTrigger。通過。
オン オン 有り 有り BのTrigger、AのTrigger。通過。
オン オン 有り 無し BのTrigger、AのTrigger。通過。
オン オフ 有り 有り(+IsKinematic) AのTrigger、BのTrigger。通過。
オン オフ 有り 有り AのTrigger、BのTrigger。通過。
オン オフ 有り 無し AのTrigger、BのTrigger。通過。
オフ オン 有り 有り(+IsKinematic) BのTrigger、AのTrigger。通過。
オフ オン 有り 有り BのTrigger、AのTrigger。通過。
オフ オン 有り 無し BのTrigger、AのTrigger。通過。
オフ オフ 有り 有り(+IsKinematic) AのCollision、BのCollision。その場で静止。
オフ オフ 有り 有り AのCollision、BのCollision。A,Bともに左に移動していく。
オフ オフ 有り 無し AのCollision、BのCollision。その場で静止。

参考

公式マニュアル

その他

おわりに

両方とも動いている場合」が気になる...

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
26
Help us understand the problem. What are the problem?