четверг, 5 апреля 2012 г.

Экранные координаты в мировые

Для того чтоб определить объект в пространстве находящийся под курсором необходимо:
1. Перевести экранные координаты указателя (мыши) в луч с использованием метода камеры camera.ScreenPointToRay()
2. Пустить луч с помощью физики с использованием метода Physics.Raycast()
3. Если луч попал в какой-то объект (объект должен иметь коллайдер, чтобы в него можно было попасть лучем).
4. Обработать результат.
using UnityEngine;
 
public class RayCastExapmle : MonoBehaviour
{
 
    // Добавте этот скрипт камере и он нарисует
    // отладочные линии треугольника, на который указывает мышка
    void Update()
    {
        // создаем луч на основе позиции мыши и компонента камеры,
        // принадлежащей текущему объекту
        Ray ray = camera.ScreenPointToRay(Input.mousePosition);
 
        // Переменная hit будет содержать результат "бросания" луча в пространство сцены
        RaycastHit hit;
 
        // Если не попали в какой-либо объект - выходим из функции
        if (!Physics.Raycast(ray, out hit))
            return;
 
        // приводим тип колайдера, в который мы попали к типу MeshCollider
        // только у этого типа колайдеров есть информация о треугольнике, в который мы попали
        MeshCollider meshCollider = hit.collider as MeshCollider;
 
        // если тип колайдера отличается от типа MeshCollider, то результат приведения будет null
        // так же проверим на наличие назначенного меша у колайдера
        if (meshCollider == null || meshCollider.sharedMesh == null)
            return;
 
        // получаем меш (записываем его в локальную переменную)
        Mesh mesh = meshCollider.sharedMesh;
 
        // получаем вершины и треугольники меша
        // рекомендую перед работой с данными меша записывать их в отдельные массивы
        // т.к. свойста обращения к данным массвам всегда при обращении создают новые экземплфры массивов
        Vector3[] vertices = mesh.vertices;
        int[] triangles = mesh.triangles;
 
        // Получаем координаты вершин меша
        var p0 = vertices[triangles[hit.triangleIndex * 3 + 0]];
        var p1 = vertices[triangles[hit.triangleIndex * 3 + 1]];
        var p2 = vertices[triangles[hit.triangleIndex * 3 + 2]];
 
        // Преобразовываем координаты вершин в глобальные
        // используя трансформ объекта, которому принадлежит колайдер
        Transform hitTransform = hit.collider.transform;
        p0 = hitTransform.TransformPoint(p0);
        p1 = hitTransform.TransformPoint(p1);
        p2 = hitTransform.TransformPoint(p2);
 
        // Рисуем в сцене выбранный треугольник
        Debug.DrawLine(p0, p1);
        Debug.DrawLine(p1, p2);
        Debug.DrawLine(p2, p0);
    }
}


3 комментария:

  1. Замечательно всё описано и не могу выразить на сколько я доволен и рад что есть такая интересная информация. Благодарю автору.

    ОтветитьУдалить
  2. Скажите пожалуйста каким образом мы храним треугольники в массиве int[] triangles = mesh.triangles
    Зачем здесь умножаем на 3?

    ОтветитьУдалить
  3. var p0 = vertices[triangles[hit.triangleIndex * 3 + 0]];

    ОтветитьУдалить