【Unity】Rayとは?光線の位置や方向を決める構造体

Ray構造体とは? Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、

「UnityのRayってなに?」

「Ray構造体を使うとどんなことができるの?」

というお悩みの方に向けた内容となっています。

Unityでは、Ray構造体を使うことで、ゲーム内で一直線に進む光線を作ることができます。

このRayは、光線を飛ばす位置の「origin」と光線を飛ばす方向の「direction」の2つのメンバ変数で、光線の情報を管理しています。

そして、Raycastメソッドを使うことで、Rayの情報を元に光線を飛ばして、コライダーを付けているオブジェクトに対して、当たり判定の処理などを作ることができます。

そこで、このページでは、UnityのRay構造体について、どんな仕組みや機能があるのか、また使い方までをまとめていきます。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

Ray構造体とは?

まずは、Ray構造体の特徴や仕組みについて紹介していきます。

特定の場所から一方向に伸びる光線を表す構造体

Rayは、ある特定の位置から一方向に向かった光線を表すことができる構造体です。

そもそも「Ray」とは、日本語で「光線」を意味している言葉で、特定の位置から真っ直ぐに進む光の情報をRay構造体で決めています。

そして、このRay構造体にはメンバ変数として、

の2つで光線の情報を表していて、それぞれVector3型で座標やベクトルを表しています。

当たり判定を検知することができる

Rayで定義した光線を飛ばして、他のオブジェクトとの当たり判定を検知することができるという特徴があります。

もう少し詳しく言えば、Ray構造体で作った光線をRaycastメソッドなどで飛ばすことができ、その光線上にコライダーの付いているオブジェクトがあった場合、その光線とオブジェクトの当たり判定を検知することができます。

このRayの特徴を使うことで、例えば、

  • マウスやスマホでタップした位置にあるオブジェクトを撤去する
  • 武器からレーザー光線を飛ばして敵を倒す

など、特定の位置から一直線上にあるオブジェクトに対しての当たり判定の処理を作ることができます。

なお、あくまでもRay構造体自体には、当たり判定を検知する機能はありません。

Ray構造体の使い方

ここからは、実際にUnityでRay構造体の使い方を紹介していきます。

光線を飛ばすためのRay構造体を作る

まずは、光線情報をRay構造体で作っていきます。

ここでは、球形のオブジェクトを配置して、このオブジェクトのから画面の奥に向かって進む光線を、スクリプト内で作っていきます。

using UnityEngine;

public class RayEmission : MonoBehaviour
{
    Ray ray;    // Ray構造体を作る

    void Start()
    {
        ray.origin = transform.position;    // オブジェクト座標を光線の飛ばし始める位置にする
        ray.direction = Vector3.forward;    // 画面の奥に向かって光線を飛ばす
    }
}

光線を飛ばし始める位置を表す変数originは、オブジェクトの座標と同じにしたいので、9行目でtransform.positionを代入しています。

また、光線を飛ばす方向を表す変数directionは、カメラから見た際に画面の奥に光線を飛ばしたいので、10行目でVector3型で方向を指定しています。

これで、飛ばす光線をRay構造体で作ることができました。

Raycastメソッドで光線を飛ばして当たり判定を作る

Ray構造体で作った光線を飛ばして、オブジェクトとの当たり判定の処理を作る場合は、Physics.Raycastメソッドが使われます。

このRaycastメソッドは、Rayを飛ばしてコライダーの付いたオブジェクトとの当たり判定があるかどうかを、bool型で返す処理を行います。

ここでは、四角いオブジェクトが時間経過とともに表示されて画面上の右に進み、そしてスペースキーを押している間に先ほど定義した球体のオブジェクトからRayの光線をRaycastで飛ばして、四角いオブジェクトと当たったら消えるという処理を作ってみます。

まずは、新しく四角いオブジェクトを配置して、コライダーを紐づけておきます。

そして、このオブジェクトに以下のスクリプトを紐づけて、表示されたら移動させるという処理を加えておきます。

using UnityEngine;

public class CubeController : MonoBehaviour
{
    float speed = 0.02f;

    void Update()
    {
        transform.Translate(Vector3.right * speed); // 右に向かって移動する

        if (transform.position.x > 13)
        {
            Destroy(gameObject);
        }
    }
}

このオブジェクトをPrefab化して削除しておき、以下のスクリプトを作って空のオブジェクトに紐づけておきます。

using UnityEngine;

public class CubeDisplay : MonoBehaviour
{
    public GameObject cube;
    Vector3 vector3 = new Vector3(-10, 6.71f, -26); // オブジェクトを表示させる座標
    float delta;
    float time = 1.0f;

    void Update()
    {
        delta += Time.deltaTime;

        if (time < delta )
        {
            Instantiate(cube, vector3, Quaternion.identity);    // オブジェクトを表示させる処理
            delta = 0;
        }
    }
}

この時点でゲームを実行すると、以下のように球体のオブジェクトよりも後ろに四角いオブジェクトが時間経過とともに表示されて、左から右に向かって移動するようになっています。

次に、球形のオブジェクトに紐づけたスクリプトを開いて、光線を飛ばす処理を作っていきます。

using UnityEngine;

public class RayEmission : MonoBehaviour
{
    Ray ray;

    void Start()
    {
        ray.origin = transform.position;
        ray.direction = Vector3.forward;
    }

    void Update()
    {
        // スペースキーを押した場合の処理
        if (Input.GetKey(KeyCode.Space))
        {
            RaycastHit hit; // 当たったオブジェクト情報
            if (Physics.Raycast(ray, out hit))
            {
                Destroy(hit.collider.gameObject);   // オブジェクトを消去する
            }

            gameObject.GetComponent<Renderer>().material.color = Color.red; // 赤色に変更
        }
        else
        {
            gameObject.GetComponent<Renderer>().material.color = Color.gray;    // 色を戻す
        }
    }
}

19行目でスペースキーを押している間、Physics.Raycastメソッドで光線を飛ばす処理を作っています。

なお、Physics.Raycastメソッドを使う際は、いくつか書き方がありますが、以下のように書いています。

Physics.Raycast(Ray ray, RaycastHit hitInfo)

引数で、飛ばす光線の情報(ray)と、光線と当たったオブジェクト情報(hitInfo)を指定しています。

また、わかりやすいように、24行目でスペースキーを押している間は、オブジェクトの色を変えるようにしています。

そして、この光線と当たったオブジェクトに対して、21行目でDestroyメソッドを使って消去する処理を作っています。

これでゲームを実行してみると、

スペースキーを押している間は光線を飛ばし、当たったオブジェクトが消去される処理が作れています。

まとめ

このページでは、Unityで使うRay構造体について、どんな特徴や仕組みがあるのか、また使い方までをまとめていきましたが、いかがでしたでしょうか?

Ray構造体とは、特定の位置から飛ばす光線のデータを管理している構造体のことで、Raycastメソッドと一緒に使われることが多いです。

このRay構造体は、メンバ変数の「origin」光線を飛ばし始める位置を指定し、「direction」光線を飛ばす方向を管理して、光線を定義しています。

また、Ray構造体で作った光線は、Raycastメソッドで飛ばすことができ、コライダーの付いたオブジェクトが光線上にある場合は、当たり判定の処理を作ることができます。

最後までお読みいただきまして、ありがとうございました!

コメント