简体   繁体   English

在3D空间中获取与相机视图对齐的点

[英]Get point in 3D space aligned to camera view

I am trying to use Frustum to detect whether or not an object is within a square part of the screen (see image below) It's a UI image working as the aimbox not a 3D object. 我正在尝试使用Frustum来检测对象是否在屏幕的正方形区域内(请参见下图)。这是一个UI图像,它用作瞄准盒而不是3D对象。

The original post is here: Detect if an object in 3D space is within/touches a UI image's bounds 原始文章在这里: 检测3D空间中的对象是否在UI图像的边界内/是否触及UI图像的边界

Right now I can get the Frustum and drawing the box to work, but only looking in one direction. 现在,我可以得到“平截头体”并绘制框以进行工作,但只能朝一个方向看。

I need to be able to calculate new points when the camera turns and I can't figure out how. 我需要能够在相机转动时计算新点,但我不知道如何计算。

The code below kinda works, but I need to offset the positions so they align with the view when the camera is moving. 下面的代码有点用,但是我需要偏移位置,以便它们在相机移动时与视图对齐。

Edit: Right now nothing is supposed to happen but drawing the box and get that to work. 编辑:现在应该什么也不会发生,只需要画一个盒子并使它工作即可。 Collision detection comes after. 碰撞检测随之而来。

// 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 https://imgur.com/iXQlE04

Simplest version: Make the aimbox a child of the camera. 最简单的版本:将瞄准器作为相机的子代。

Alternative Solution, use camPosOffset also for the first 4 verts like this: 替代解决方案,也对前四个版本使用camPosOffset,如下所示:

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;

After fiddling for almost two days I got exactly what I wanted. 摆弄了将近两天后,我得到了我想要的东西。

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

Here the altered frustum view follows the camera at any given time. 在这里,在任何给定时间,更改后的视锥视图都会跟随相机。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM