【问题标题】:Get point in 3D space aligned to camera view获取与相机视图对齐的 3D 空间中的点
【发布时间】:2018-07-16 01:19:03
【问题描述】:

我正在尝试使用 Frustum 来检测一个对象是否在屏幕的正方形部分内(见下图)这是一个 UI 图像,作为目标框而不是 3D 对象。

原帖在这里:Detect if an object in 3D space is within/touches a UI image's bounds

现在我可以让 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

【问题讨论】:

  • 为什么不把盒子碰撞器(Aimbox)加长,只检测物体是否完全在盒子内?
  • @Hristo 因为沿着那条路线走,盒子的末端会变得越来越小,目标越远,无论如何在视觉上都很好。所以瞄准框会因为透视而关闭。

标签: c# unity3d camera rotation frustum


【解决方案1】:

最简单的版本:使目标框成为相机的子项。

替代解决方案,对前 4 个顶点也使用 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;

【讨论】:

  • 由于瞄准框的其他功能,我小时候无法拥有它。而且,它是一个图像,据我所知,我不能用它来确定是悬停在还是部分悬停在 3D 对象上。不过我找到了一个解决方案,我刚刚发布了。仅从您的代码中,我无法判断您的代码是否做同样的事情。感谢您的回答:)
  • 好吧,您的解决方案在前 4 个顶点中使用了cam.transform.forward,这是我的(部分)观点。您之前将它们放在凸轮位置,因此它不受旋转的影响。 (基本上是你的问题)所以我希望我的例子对你有所帮助。很高兴你解决了它
【解决方案2】:

摆弄了将近两天后,我得到了我想要的。

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

此处更改后的视锥体视图在任何给定时间都跟随相机。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 2012-06-08
    • 2018-10-30
    • 2014-02-02
    • 2022-06-12
    相关资源
    最近更新 更多