トリガーイベントをカメラで見たタイミングで発火したいと思ったから作ってみた。

対象オブジェクトにヒットする度にイベントが発火できる様、ヒットさせるオブジェクト側にスクリプトを紐づけたりすると保守的に楽。

こんな感じで、見たものを消したりアウトラインつけたりできる。

Private / Publicの設定

変数設定。オブジェクトとRayとの距離と、当たり判定となるオブジェクトは後から変更したいからpublicに設定。メインカメラは固定。

private Camera camera; //レイを出すメインカメラ
public float rayDistance = 2f; //レイと対象オブジェクトとの距離
public GameObject RayObject; //対象オブジェクト

上の設定でUnity側でオブジェクトとRayの長さを自在に変更可能にしとく。

Ray Objectに入れるオブジェクトが直接トリガーとなるオブジェクト。

メインカメラをキャッシュ

カメラは重いので、Start関数のタイミングで事前にキャッシュ。

void Start(){
  camera = Camera.main; //メインカメラをキャッシュ
}

確認用にGizmosでRayを出力

distanceを制御できる様にしてるから、シーンビューのデバッグ時にRayがどの程度出ているか確認用に記述。また分かりやすい様にRayを赤色で出力。

特にGizmosで確認しない場合はOnDrawGizmos関数は削除しても良いかも。

void OnDrawGizmos(){
  camera = Camera.main;
  Debug.DrawRay(camera.transform.position, camera.transform.forward * rayDistance, Color.red);
}

オブジェクトにヒットしたタイミングで条件分岐

アップデート関数でトリガーイベントと紐づける。

該当のオブジェクトに当たるとイベントが発火する様にしたいのでhit.transform.gameObject == RayObjectで条件分岐させて、当たった場合にはtriggerEvent.Invoke();でトリガーイベントを呼び出す。

これで完成。

可能ならtransformのキャッシュを行っておく。

void Update(){
    Ray ray = new Ray(camera.transform.position, camera.transform.forward);
    RaycastHit hit;

    if(Physics.Raycast(ray,out hit,rayDistance)){
        //RayObjectにhitした場合
        if(hit.transform.gameObject == RayObject){
            triggerEvent.Invoke();
        }
    }
}

あとはトリガーイベントで好みのトリガーを設定。

さいごに

コライダーイベントでも十分便利だけど、レイキャストでトリガーイベントが行えると、視点のタイミングでイベントを発火できるので何かといい。

だけどずっとRayが出ている状態は重くなる(気がする)のでコライダーイベントと併用とか、もしくはレイキャストイベントは終了時にenableオフしてもいいかも。