Получить точку в трехмерном пространстве, выровненную с видом камеры

Я пытаюсь использовать Frustum, чтобы определить, находится ли объект в квадратной части экрана (см. Изображение ниже). Это изображение пользовательского интерфейса, которое работает как прицел, а не как 3D-объект.

Оригинальный пост здесь: Определите, находится ли объект в трехмерном пространстве в пределах / касается границ изображения пользовательского интерфейса

Прямо сейчас я могу заставить Frustum и рисовать коробку, чтобы работать, но только смотря в одном направлении.

Мне нужно уметь вычислять новые точки, когда камера поворачивается, и я не могу понять, как.

Код ниже вроде работает, но мне нужно сместить позиции, чтобы они совпали с видом, когда камера движется.

Изменить: Прямо сейчас ничего не должно произойти, кроме рисования коробки и заставить это работать. Обнаружение столкновения приходит после.

// Draw aimbox
Vector3 camPosOffset = camPos + cam.transform.forward * maxDistance;

float frustumHeight = (2.0f * maxDistance * Mathf.Tan(cam.fieldOfView * 0.5f * Mathf.Deg2Rad));

cubeVerts[0] = new Vector3(camPos.x, camPos.y, camPos.z);
cubeVerts[1] = new Vector3(camPos.x, camPos.y, camPos.z);
cubeVerts[2] = new Vector3(camPos.x, camPos.y, camPos.z);
cubeVerts[3] = new Vector3(camPos.x, camPos.y, camPos.z);
cubeVerts[4] = new Vector3(camPosOffset.x - frustumHeight, camPosOffset.y + frustumHeight, camPosOffset.z);
cubeVerts[5] = new Vector3(camPosOffset.x + frustumHeight, camPosOffset.y + frustumHeight, camPosOffset.z);
cubeVerts[6] = new Vector3(camPosOffset.x - frustumHeight, camPosOffset.y - frustumHeight, camPosOffset.z);
cubeVerts[7] = new Vector3(camPosOffset.x + frustumHeight, camPosOffset.y - frustumHeight, camPosOffset.z);

for (int i = 0; i < edges.Length; i += 2)
{
    Debug.DrawLine(cubeVerts[edges[i]], cubeVerts[edges[i + 1]], Color.red);
}

https://imgur.com/iXQlE04

2 ответа

Простейшая версия: сделайте прицел детской дочерью камеры.

Альтернативное решение, используйте camPosOffset также для первых 4 вертов:

cubeVerts[0] = new Vector3(camPosOffset.x - frustumHeight, camPosOffset.y + frustumHeight, camPosOffset.z);
cubeVerts[1] = new Vector3(camPosOffset.x + frustumHeight, camPosOffset.y + frustumHeight, camPosOffset.z);
cubeVerts[2] = new Vector3(camPosOffset.x - frustumHeight, camPosOffset.y - frustumHeight, camPosOffset.z);
cubeVerts[3] = new Vector3(camPosOffset.x + frustumHeight, camPosOffset.y - frustumHeight, camPosOffset.z);
cubeVerts[4] = new Vector3(camPosOffset.x - frustumHeight, camPosOffset.y + frustumHeight, camPosOffset.z) + cam.forward * 3;
cubeVerts[5] = new Vector3(camPosOffset.x + frustumHeight, camPosOffset.y + frustumHeight, camPosOffset.z) + cam.forward * 3;
cubeVerts[6] = new Vector3(camPosOffset.x - frustumHeight, camPosOffset.y - frustumHeight, camPosOffset.z) + cam.forward * 3;
cubeVerts[7] = new Vector3(camPosOffset.x + frustumHeight, camPosOffset.y - frustumHeight, camPosOffset.z) + cam.forward * 3;

После двухдневной игры я получил именно то, что хотел.

        //Draw aimbox

    float frustumHeight = ((2.0f * maxDistance * Mathf.Tan(cam.fieldOfView/20 * 0.5f * Mathf.Deg2Rad))); //cam.fieldOfView/20, I divide by 20 because I only need a small square of the view

    cubeVerts[0] = cam.transform.position + cam.transform.forward * 25; //25 is the distance from the camera to the object it follows
    cubeVerts[1] = cam.transform.position + cam.transform.forward * 25;
    cubeVerts[2] = cam.transform.position + cam.transform.forward * 25;
    cubeVerts[3] = cam.transform.position + cam.transform.forward * 25;
    cubeVerts[4] = cam.transform.position + (cam.transform.right * -frustumHeight) + (cam.transform.up * frustumHeight) + (cam.transform.forward * maxDistance);
    cubeVerts[5] = cam.transform.position + (cam.transform.right * frustumHeight) + (cam.transform.up * frustumHeight) + (cam.transform.forward * maxDistance);
    cubeVerts[6] = cam.transform.position + (cam.transform.right * -frustumHeight) + (cam.transform.up * -frustumHeight) + (cam.transform.forward * maxDistance);
    cubeVerts[7] = cam.transform.position + (cam.transform.right * +frustumHeight) + (cam.transform.up * -frustumHeight) + (cam.transform.forward * maxDistance);

    for (int i = 0; i < edges.Length; i += 2)
    {
        Debug.DrawLine(cubeVerts[edges[i]], cubeVerts[edges[i + 1]], Color.red);
    }

Здесь вид измененного усеченного контура следует за камерой в любой момент времени.

Другие вопросы по тегам