Unityで距離測定器(Raycast)

Raycastでオブジェクトの距離を計測してみた。ただこれだけではほかにもやっている人が大量にいるので、複数の距離計測機から情報を1つにまとめられるものも作った。

マニュアルは以下のページ。

Physics-Raycast - Unity スクリプトリファレンス

イメージとしては、ある地点からある方向に弾を飛ばして、物体にあたるまでの距離を計測する。 使い方としては以下の通り。

bool Raycast (Vector3 origin, Vector3 direction, RaycastHit hit, float maxDistance)
  • origin: 距離計測をする開始地点。上記説明のある地点のこと。
  • direction: 距離計測をする方向。上記説明のある方向のこと。
  • hit: あたった物体の情報。上記説明の弾に当たった物体の情報のこと。
  • maxDistance: 計測する最大距離。上記説明の弾が飛ぶ距離のこと。

使ってみる

① 空のオブジェクトを作成し、DistanceSensor1と名前を付ける。

② DistanceSensor.csというスクリプトを作成し、以下をコピペ。

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

public class DistanceSensor : MonoBehaviour
{
    private const float NOTHING = -1;
    // Rayを表示するか
    public bool drow_ray = false;
    // 測定可能範囲
    public float maxDistance = 30;
    [System.NonSerialized] public float distance;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    void Update()
    {
        Vector3 fwd = transform.TransformDirection(Vector3.forward);
        RaycastHit hit;
        if (Physics.Raycast(transform.position, fwd, out hit, maxDistance))
        {
            distance = hit.distance;
        }
        else
        {
            distance = NOTHING;
        }
        if (drow_ray)
        {
            Debug.DrawRay(transform.position, fwd * maxDistance, Color.red, 0, false);
        }
        Debug.Log(distance);
    }
}

③ 1で作ったオブジェクトに、2で作ったスクリプトをアタッチする。

④距離計測の対象を作る。球や箱など適当なオブジェクトを作成して、矢印などで操作できるようにする。参考↓

【Unity C#】キー操作で上下左右、前後の移動 - フタバゼミ

⑤距離計測の対象オブジェクトに、ColliderとRidgedbodyを付ける。(これをしないとRaycastが当たらない)

以上を行って、ゲームプレイしてみる。Rayを表示したい場合は、①で作ったオブジェクトのInspectorのdrow_rayにチェックを入れる。表示されない場合は、Game画面右上のGizmosをクリックする。

オブジェクトを動かしてRayに当てるとConsoleに距離が表示される。

複数の距離計の情報をまとめる

複数方向の距離を計測したいとき、情報をまとめてられていると便利なので、まとめる。

①空のオブジェクトを作成し、DistanceSensorBaseと名前を付ける。

②以下のスクリプトをアタッチする。距離情報はdistancesにリストとして保持される。順序は③で説明するObjectsの順序と同じ。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Data;
using System.Linq;

public class DistanceSensorBase : MonoBehaviour
{
    public List<DistanceSensor> objects;
    [System.NonSerialized] public List<float> distances = new List<float>();
    private int n;

    // Start is called before the first frame update
    void Start()
    {
        n = objects.Count;
        distances = Enumerable.Repeat<float>(0.0f, n).ToList();
    }

    // Update is called once per frame
    void Update()
    {
        string s = "";
        for (int i = 0; i < objects.Count; i++)
        {
            distances[i] = objects[i].distance;
            s = s + " " + distances[i].ToString();
        }
        Debug.Log(s);
    }
}

③①で作ったオブジェクトのInspectorで、Objectsに先ほど作った距離計測機を追加する。距離計測機は好きなだけ追加可能。

動かしてみると、以下のように各計測器で距離が計測できていることがわかる。