Version: 2017.4
Dolly Zoom (эффект "Trombone")
Использование наклонной пирамиды видимости (Oblique Frustum)

Лучи из камеры

В секции Основные сведения об усечённой пирамиде видимости было рассказано, что любая точка в поле зрения камеры соответствует линии в мировом пространстве. Иногда полезно иметь математическое представление этой линии и Unity может предоставить его в виде объекта Ray (луч). Ray всегда соответствует точке в поле зрения, потому класс Camera предоставляет методы ScreenPointToRay и ViewportPointToRay. Различие между ними в том, что ScreenPointToRay ожидает точку в виде пиксельных координат, в то время как ViewportPointToRay получает нормализованные координаты в диапазоне от 0 до 1 (где 0 представляет нижнюю или левую, а 1 - верхнюю или правую часть поля зрения). Каждая из этих функций возвращает Ray, который состоит из точки испускания (начала) и вектора, показывающего направление линии из этой точки. Ray берёт начало из ближней плоскости отсечения вместо точки transform.position камеры.

Рейкастинг

Луч из камеры чаще всего используют для совершения рейкаста в сцену. Рейкаст отправляет воображаемый “лазерный луч” вдоль программного луча из точки испускания до тех пор, пока он не встретит на пути коллайдер в сцене. В результате столкновения с коллайдером, возвращается RaycastHit с координатами и объектом столкновения. Это очень полезный способ нахождения объекта по его изображению на экране. Например, с помощью следующего кода можно определить объект под указателем мышки:-

C# script example:

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.
        }
    }
}

JS script example:

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

if (Physics.Raycast(ray, hit)) {
    var objectHit: Transform = hit.transform;
    
    // Do something with the object that was hit by the raycast.
}

Перемещение камеры вдоль луча

Иногда полезно получить луч, соответствующий точке на экране и затем переместить камеру вдоль этого луча. Например, вы могли бы позволить пользователю выбрать объект мышкой и затем приблизить его, при этом сохраняя его “приколотым” к одному и тому же положению на экране под курсором мышки (это может быть полезно, когда камера смотрит на тактическую карту, например). Код, позволяющий это сделать, довольно прост:-

C# script example:

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 script example:

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

Dolly Zoom (эффект "Trombone")
Использование наклонной пирамиды видимости (Oblique Frustum)