Unityのraycastを使って出来ることをまとめました
19/02/13 19:03:03 19/02/17 19:54:23
raycastはオブジェクトの当たり判定を行うもので、オブジェクトに当たったかどうかがわかります。
キャラクター同士や壁との接触であれば座標を取得するクラスを使用することも多いですが、たとえば銃で撃ってそれが当たったかどうかを判定するようなときは座標取得のクラスでは実装できません。
そこで便利なのがraycastで、シューティングゲームでは銃を撃って球が相手に当たったかどうか判定できます。このページでは、より具体的にraycastの機能を解説し、何ができるのかを確認していきます。
raycastとは
まずrayを和訳すると光線です。raycastはオブジェクトから透明な光線を出し、それを他のオブジェクトに当てることで当たり判定を行う方法になります。raycastの基本的な書き方は以下のようになります。
Physics.Raycast(Vector3 origin(rayの開始地点), Vector3 direction(rayの向き,RaycastHit hitInfo(当たったオブジェクトの情報を格納), float distance(rayの発射距離), int layerMask(レイヤマスクの設定));
要素が多いですが、特に重要なのは開始地点と向きです。ここが間違っていると当たり判定は意図したものとまったく異なってしまいます。
raycastの使い方
raycastの概要を説明しましたが、次に実際のサンプルコードを紹介します。以下はマウスカーソルのある位置からRayを飛ばし、オブジェクトに当たるかどうか判定するコードです。
private void Update () {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity)){
Debug.Log(hit.collider.gameObject.name);
}
}
rayの使い方として、直接指定する方法と発射位置と方向を設定する方法もあります。直接指定は上記のサンプルコードにも含まれており、以下の部分です。
Physics.Raycast(ray, out hit, Mathf.Infinity);
発射位置と方向を指定する場合以下のようになります。
Physics.Raycast (startPoint, direction, out hit, Mathf.Infinity);
raycastのサンプルコード
rayの作成、距離の取得、可視化、といった諸々を含めたサンプルコードを紹介します。
public class RayTest : MonoBehaviour {
public LayerMask mask;
void Ray() {
Ray ray = new Ray(transform.position, transform.forward);
Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 10.0f, mask)) {
hit.collider.GetComponent<MeshRenderer>().material.color = Color.red;
Destroy(hit.collider.gameObject);
this.transform.position = hit.point;
float dis = hit.distance;
hit.collider.enabled = false;
}
RaycastHit[] hits = Physics.RaycastAll(ray, Mathf.Infinity);
foreach(var obj in hits) {
switch(obj.collider.tag) {
case "Red":
obj.collider.GetComponent<MeshRenderer>().material.color = Color.red;
break;
case "Blue":
obj.collider.GetComponent<MeshRenderer>().material.color = Color.blue;
break;
case "Green":
obj.collider.GetComponent<MeshRenderer>().material.color = Color.green;
break;
default:
obj.collider.gameObject.SetActive(false);
break;
}
}
if(Physics.SphereCast(ray, 5.0f, out hit, 10.0f)) {}
Debug.DrawRay(ray.origin, ray.direction, Color.red, 3.0f);
UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject();
if(!UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject() && Input.GetMouseButtonDown(0)) {
}
}
}
これでRayの作成、Physics.Raycastで衝突判定、Rayの太さを変える、Rayの可視化、マウスがUIを選択しているかどうかの判定、といったことを行っています。
地面の接触判定
raycastはどのオブジェクトに対しても使えるので地面に対して使っても問題ないのですが、精度が落ちます。
地面のように固定されているオブジェクトに対しては、raycastではなく GetContactsやIsTouchingを使った方が確実です。サンプルコードは以下になります。
using UnityEngine;
public class TouchTest : MonoBehaviour {
[SerializeField] UnityEngine.UI.Text label;
[SerializeField] ContactFilter2D filter2d;
void Update ()
{
var isTouched = GetComponent<Rigidbody2D>().IsTouching(filter2d);
label.text = string.Format("Touch : {0}", isTouched);
}
}
まとめ
raycastは便利な機能で、上で説明した通り銃やその他微妙な角度等で当たり判定の難しい処理も実現できます。そのため他のオブジェクトが重なっているかどうか判定するクラスとは異なるのですが、処理が重くなるというデメリットもあります。
なので、raycastを使わなくても良い場面ではなるべく使用しないことをおすすめします。少なくとも、地面や壁との当たり判定は他の方法でも実装可能なので、rayで見えない線を引いて判定する必要はありません。
raycastを使えばどのような形でも二つのオブジェクトの当たり判定ができますが、特に高度なもののみに使用した方が良いということを覚えておいてください。
【Unity関連記事】
▼Unityの基礎編
・ 【unityのフリーランス求人・案件情報】エンジニア需要や開発単価、未経験でもいける?
・ 【unity入門】ゲーム開発だけじゃない、Unityで出来ること
▼Unityの外部アセット、リソース編
・ UnityでMMDモデルを自由自在に動かしてみよう!
・ Unity adsを使って簡単に広告を導入しよう
・ Unityのアセットストアの上手な使い方
・ Unityで作られているARアプリをまとめてみました
▼Unityのコンポーネント編
・ Unityのrigidbodyを使って物理演算を導入してみよう
・ コードを使わずにUnityでキャラ追従のカメラを作る方法
・ Unityで簡単にアニメーションを作成する方法をまとめました
・ Unityでオブジェクトを回転させる方法をわかりやすくまとめました
・ Unityのtransformを使ってオブジェクトの座標や回転を操作する
・ Unityのアニメーターを簡単に作成する方法まとめ
・ UnityのShaderの解説と使い方まとめました
・ Unityで「当たり判定」(衝突判定)を付ける方法
・ Unityのgetcomponentの上手な使い方と使用時の注意点まとめ
・ Unityでキャラの移動を制御する方法まとめ
・ (この記事)Unityのraycastを使って出来ることをまとめました
▼Unityのデフォルト機能、ゲーム製作編
・ blenderで作ったオブジェクトをUnityで組み込んでみよう
・ Unityのコルーチンとは?使い方をまとめました
・ Unityで作られているRPGゲームを作るための6つのステップ
・ Unityのパーティクルを使って演出できるエフェクト例
・ UnityでのUIデザインの基礎をまとめてみました
・ Unityのcloud buildの便利な点をまとめました
・ Unityを使って半日でFPSゲームを作ってみよう
人気記事