こんにちは、ともくんのゲーム作り部屋にようこそ!
このページでは、
「UnityのScreenPointToRayってなに?」
「ScreenPointToRayってどうやって使うの?」
というお悩みの方に向けた内容となっています。
Unityでは、マウスのクリックやスマホのタップ操作において、ScreenPointToRayメソッドが使われます。
ScreenPointToRayとは、カメラからスクリーン画面の座標に対してのベクトルを取得することができるメソッドです。
このScreenPointToRayを使うことで、例えばマウスでクリックした場所に弾を撃ったり、物を投げたりすることができるようになります。
そこで、このページでは、UnityのScreenPointToRayについて、どんなメソッドなのか、また使い方までをまとめていきます。
ScreenPointToRayとは?
まずは、ScreenPointToRayメソッドの特徴や仕様についてまとめていきます。
カメラからスクリーン座標に向かうベクトルを取得できる
ScreenPointToRayとは、カメラからスクリーン座標の一カ所に向かったベクトルを取得することができるCameraコンポーネントで定義されているメソッドです。
もう少し詳しく説明すると、スクリーン座標とは、ゲーム内のワールド座標とは異なり、カメラで描写している画面における座標のことで、ゲームを起動した際にゲーム内をマウスでクリックしたりスマホでタップしているのがスクリーン座標です。
そのスクリーン座標の一点に対して、カメラオブジェクトからの一直線のベクトルを取得できるのがScreenPointToRayとなっています。

返り値はRayクラスで取得する
ScreenPointToRayで取得できるベクトルは、Rayクラスで取得することになります。
Rayとは光線のことで、ScreenPointToRayではカメラからスクリーン座標への一点に向かって、光で繋いだ線のベクトルを取得できることになります。
このRayには、光源となる座標の「origin」と、光線の方向を示す「direction」というメンバ変数を持っていて、ScreenPointToRayで取得する値は、originがカメラの座標位置となり、directionがそのカメラからスクリーン座標への一点に向かうベクトルということになります。

また、Rayには他にも、光線上にあるコライダーを付けているオブジェクトに対して、当たり判定を検知することもできます。
ゲーム内をクリック・タップする操作で使われる
ScreenPointToRayは、ゲーム内でマウスを使ってクリックしたり、スマホでタップする操作で使われるメソッドになっています。
ゲーム画面をクリック・タップする操作は、スクリーン画面での座標を取得することになるため、ScreenPointToRayを使ってワールド座標に対してのベクトルを取得することができます。
例えば、マウスでクリックした場所に向かってアイテムやオブジェクトを投げるといったことが、ScreenPointToRayでできるようになります。
また、他にも当たり判定の機能を使うことで、表示された敵をタップして倒していく処理や、配置されているコインをタップして獲得していくといった処理でもScreenPointToRayが活用できます。
ScreenPointToRayの使い方
ここからは、ScreenPointToRayの使い方についてまとめていきます。
Cameraコンポーネントを取得する
ScreenPointToRayは、Cameraコンポーネントで定義されているメソッドになるので、「Camera.ScreenPointToRay」として先にCameraコンポーネントを取得して指定する必要があります。
ただ、「Main Camera」というタグが設定されているカメラであれば、「Camera.main.ScreenPointToRay」と書くだけで、コンポーネントを取得する必要はありません。

プロジェクトを立ち上げてデフォルトで設定されているカメラは、上記のようにタグ設定がされていると思います。
もし、この「Main Camera」のタグが設定されていないカメラで、ScreenPointToRayを使う場合は、GetComponentメソッドを使ってCameraコンポーネントを取得しておきましょう。
引数にスクリーン座標を指定する
ScreenPointToRayを使う場合は、引数にスクリーン座標を指定します。
ScreenPointToRay(スクリーン座標);
ここで指定したスクリーン座標に対して、カメラからのベクトルをRayクラスで取得することができるようになっています。
例えばよく使うのが、マウスでクリックした位置やスマホでタップした場所を指定したい場合として、「Input.mousePosition」を引数に指定します。
ScreenPointToRay(Input.mousePosition);
「Input.mousePosition」とは、スクリーン座標におけるマウスのカーソル位置をVector3型で取得できるInputクラスのプロパティです。
この「Input.mousePosition」をScreenPointToRayの引数に指定することで、カメラからマウスのカーソルやスマホのタップしている座標へ向かうベクトルを取得することができます。
マウスでクリックした場所に向かう処理を作る
ScreenPointToRayを実際に使って、マウスでクリックした方向に向かってオブジェクトを飛ばすといった処理を作ってみます。
まず、キューブ型のオブジェクトを配置して、Rigidbodyコンポーネントを付けておきます。

そして、このオブジェクトに対して、以下の「CubeController」というスクリプトを紐づけておきます。
using UnityEngine;
public class CubeController : MonoBehaviour
{
public void Shoot(Vector3 vector3)
{
GetComponent<Rigidbody>().AddForce(vector3); // 引数のベクトルの力を加える処理
}
}
スクリプトの中で、Shootというメソッドを作っていて、別のスクリプトから呼び出された際に引数に指定した力のベクトルが、AddForceによって加わるという処理が行われます。
ここまでできたら、オブジェクトをPrefab化しておきます。

次に、空のオブジェクトを作成して、以下のスクリプトをアタッチしておきます。
using UnityEngine;
public class ShootObject : MonoBehaviour
{
public GameObject cube;
Ray ray;
void Update()
{
// マウスをクリックした場合
if (Input.GetMouseButtonDown(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition); // マウスカーソルのスクリーン座標のベクトルを取得
GameObject clone = Instantiate(cube); // オブジェクトを表示させる
clone.transform.position = ray.origin; // 表示位置をカメラの位置に移動させる
clone.GetComponent<CubeController>().Shoot(ray.direction * 1000); // Shootメソッドを呼び出して力を加える
}
}
}
最初の5行目でGameObject型の変数cubeをpublicを付けて宣言しておき、インスペクターウィンドウからPrefab化したCubeのオブジェクトを代入しておきます。

次に、13行目でマウスをクリックした場合に、ScreenPointToRayでカメラからマウスのカーソル位置に向かうベクトルをray変数で取得しておきます。
そして、14行目でInstantiateでPrefab化したキューブを表示させる処理を行います。
また、15行目でキューブの座標位置を光源(カメラ)の位置である「ray.origin」で代入して、16行目で先ほど作ったShootメソッドの引数に「ray.direction」で取得したベクトルを指定してあげます。
これでゲームを実行してみると、

マウスでクリックした場所に向かって、カメラの位置からオブジェクトを飛ばす処理を作ることができました。
まとめ
このページでは、Unityで使うことができるScreenPointToRayメソッドについて、どんな機能なのか、また使い方までをまとめていきましたが、いかがでしたでしょうか?
ScreenPointToRayとは、カメラからスクリーン座標に向かうベクトルを取得することができるCameraコンポーネントで定義されているメソッドです。
このScreenPointToRayを使うことで、マウスでクリックした位置やスマホでタップした場所に対しての処理を作ることができます。
また、ScreenPointToRayで取得できるベクトルはRayクラスになっているので、コライダーの付いたオブジェクトとの当たり判定を検知することもできます。
最後までお読みいただきまして、ありがとうございました!
コメント