Unityで衝突判定【Trigger】
プレイヤーが他のオブジェクトにあたった時にコンソールにメッセージを表示させようと思った時にちょっと詰まったので自分用のメモです。Unityは独学で勉強し始めたばかりなので間違っている点などありましたらご指摘いただけると幸いです。
今回やりたいこと
上の画像が今回動かしていくシーンです。青い球の下にあるキューブが動かしていくプレイヤーで、左右矢印キーで壁と垂直方向にのみ動くようになっています。キューブの左右の壁がプレイヤーとの衝突判定をさせたいオブジェクトです。今回の目的は、単純にプレイヤーが左右の壁に触れたらコンソールにメッセージを表示するという挙動の実装です。上の2つの球は今回はまったく関係ありませんが、消すのが面倒だったので無視してください笑
トリガーと当たり判定
Unityで衝突判定をするには似て非なる2種類があるそうで、それがトリガーと当たり判定です。この2つの違いは単純で、衝突判定時に物理的動作(反射等?)を伴うのが当たり判定、物理動作なしにただ他の処理の引き金となるものがトリガーということで、それぞれ用途別に使い分ける必要があり、さらに必要な条件、使う関数が異なります。今回はトリガーのほうを選択して実装していきます。
準備
今回特に注意する条件は3つで、1つ目は衝突の主体どちらか一方がRigidbodyのComponentを持つこと、2つ目は両方のオブジェクトがColliderのComponentを持つことです。Rigidbodyはオブジェクトに物理的特性を与える要素、Colliderはそのオブジェクトのもつ領域を定義する要素で、衝突判定を行うときにその領域同士が触れ合うと判定が起こります。つまり、Collider要素を持たないオブジェクトは、衝突判定の観点から見ればそこに存在しないのと同じということになります。これら2つの条件は当たり判定を行うときにも必要になってくる条件です。最後の条件はTriggerで判定を行うのに必要な条件でオブジェクトのis Triggerにチェックを入れておくことです。is Triggerが外れている場合オブジェクト同士の物理的接触が起こる可能性があります。
スクリプト
以下のC#スクリプトをプレイヤーオブジェクトに紐付ければ衝突判定の実装が完成です。プレイモードで再生してプレイヤーを左右に動かし、左右の壁に当たると"Hit! (Rightwall or Leftwall)"のメッセージがコンソールに表示されます。今回使用した関数はOnTriggerEnterでこれはオブジェクトが衝突したときにカッコ内の処理を実行するような関数で、衝突相手が引数として渡されています。トリガー型の衝突判定を実装する関数としては他にも衝突している間処理を実行し続けるOnTriggerStay、離れたときに処理が実行されるOnTriggerExitがあります。ここでは、衝突対象によって表示されるメッセージを変えるために衝突対象オブジェクトからother.nameでオブジェクトの名前を取得してHit!の文字列と連結しています。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerScript : MonoBehaviour { // この部分で衝突判定と衝突時の動作を記述 void OnTriggerEnter(Collider other){ Debug.Log("Hit! " + other.name); } // ここまで // Use this for initialization void Start () { } // Update is called once per frame void Update () { // キー入力で左右に動くプログラム if(Input.GetKey(KeyCode.RightArrow)){ transform.position += new Vector3(3.0f, 0.0f, 0.0f) * Time.deltaTime; } if(Input.GetKey(KeyCode.LeftArrow)){ transform.position -= new Vector3(3.0f, 0.0f, 0.0f) * Time.deltaTime; } } }
結果
きちんと衝突時にコンソールにメッセージを表示させることができました。次回は、当たり判定の実装に挑戦してみたいと思います。
追記
コードの該当箇所を、下のように変更してis Triggerのチェックを外したら当たり判定型の衝突判定を実装することができました。動画には入っていませんがもちろんコンソールにはメッセージが表示されています。
void OnCollisionEnter(Collision other){ Debug.Log("Hit! " + other.gameObject.name) ; // Collisionはname変数を直接は持たないためgameObject変数の持つname変数を取得して表示 }
参考
【Unity】『当たり判定』でチェックすべき10のポイント
Collider - Unity スクリプトリファレンス
Collider.OnTriggerEnter(Collider) - Unity スクリプトリファレンス
オブジェクトの移動については以下の記事からコードを拝借しました
C#--キー入力: Unity入門 & ゲーム制作