天天看點

從相機發出的射線

原文連結:從相機發出的射線

在[了解視錐]

      • Raycasting
      • 沿着一條射線移動相機

(https://docs.unity3d.com/Manual/UnderstandingFrustum.html)部分中,解釋了相機視圖中每個點都對應世界空間中的一條線。對這條線進行數學表達有時候很有用,Unity使用Ray對象的形式提供這個功能。射線總是對應視圖中的一個點,是以Camera類提供了ScreenPointToRay和ViewPointToRay函數。兩者的差別是,ScreenPointToRay接收以像素形式提供的點坐标,而ViewportPointToRay接收歸一化後的坐标(0代表視圖的底部和左邊,1代表視圖的頂部和右邊)。兩者都傳回一條射線,包含射線原點,和一個表示射線方向的向量。射線從近裁切平面發出,而不是相機的transform位置。

Raycasting

相機發出的射線最常見的用途,是向場景中進行raycast。raycast從原點沿着射線方向發出想象的“雷射束”,直到碰到場景中的collider。碰撞物體的資訊和碰撞點的資訊會在一個RaycastHit對象中傳回。這在根據螢幕上的圖像來定位一個物體時非常有用。比如目前滑鼠位置處的物體可以使用下面的代碼确定:

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;

            // Do something with the object that was hit by the raycast.
        }
    }
}
           

沿着一條射線移動相機

擷取一個螢幕點對應的射線後,沿着射線移動相機的功能有時候很有用。比如說,想要根據使用者目前選中的物體放大螢幕,同時保持物體固定在相同的螢幕位置(比如使用相機檢視一個戰術地圖時也許有用)。實作這個功能的代碼很簡單:

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);
        }
    }
}