Version: 2019.3
言語: 日本語
カメラからの距離で求める錐台のサイズ
斜めの錐台を使用

カメラからのレイ

視錐台を理解する のセクションではカメラビューのどの点でもワールド空間の線に対応することを説明しました。その線を数学的に表現することが便利なときがあるので、Unity はこれを レイ オブジェクトという形で提供しています。レイはつねにビューの点に対応するので、Camera クラスは ScreenPointToRayViewportPointToRay 関数を提供しています。この 2 つの違いは ScreenPointToRay が点をピクセル座標として表すのに対して、ViewportPointToRay は正規化された座標を 0..1 の範囲 (ビュー上で 0 が左または下、1 が右または上) で表します。この各々の関数は、原点とそこからの向きを表すベクトルから構成されるレイを返します。レイはカメラの transform.position ではなくニアクリップ面を起点としています。

レイキャスティング

カメラからのレイのもっとも一般的な使用方法は レイキャスト をシーンに向かって実行することです。レイキャストは仮想の “レーザービーム” をシーンのコライダーに衝突するまで、その原点からレイに沿って発します。次に、レイキャストがヒットしたオブジェクトとヒットした点に関する情報が、RaycastHit オブジェクトによって返されます。これは画面上の画像に基づいてオブジェクトを見つけるのに便利な方法です。例えば、マウス位置にあるオブジェクトは次のコードで判定できます。

C# スクリプトの例

using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public Camera camera;

    void Start(){
        RaycastHit hit;
        Ray ray = camera.ScreenPointToRay(Input.mousePosition);
        
        if (Physics.Raycast(ray, out hit)) {
            Transform objectHit = hit.transform;
            
            // レイに当たったオブジェクトで何かをする
        }
    }
}

JS スクリプトの例

var hit: RaycastHit;
var ray: Ray = camera.ScreenPointToRay(Input.mousePosition);

if (Physics.Raycast(ray, hit)) {
    var objectHit: Transform = hit.transform;
    
    // レイに当たったオブジェクトに何かをする
}

レイに沿ったカメラの移動

画面位置に対応するレイを取得してカメラをそれに沿って移動させると便利な場合があります。例えば、ユーザーがオブジェクトをマウスで選択して、同じ画面位置をマウスで “維持” しながらズームインしたい場合があるかもしれません (例えば、戦略マップなどで便利かもしれません)。これを行うためのコードは比較的容易です。

C# スクリプトの例

using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public bool zooming;
    public float zoomSpeed;
    public Camera camera;

    void Update() {
        if (zooming) {
            Ray ray = camera.ScreenPointToRay(Input.mousePosition);
            float zoomDistance = zoomSpeed * Input.GetAxis("Vertical") * Time.deltaTime;
            camera.transform.Translate(ray.direction * zoomDistance, Space.World);
        }
    }
}

JS スクリプトの例

var zooming: boolean;
var zoomSpeed: float;

if (zooming) {
    var ray: Ray = camera.ScreenPointToRay(Input.mousePosition);
    zoomDistance = zoomSpeed * Input.GetAxis("Vertical") * Time.deltaTime;
    camera.transform.Translate(ray.direction * zoomDistance, Space.World);
}

カメラからの距離で求める錐台のサイズ
斜めの錐台を使用