计算网格边缘之间的距离

时间:2017-06-21 20:17:34

标签: c# unity3d raycasting units-of-measurement mesh-collider

我的鼠标在屏幕上就是这样的原点,

            ray = Camera.main.ScreenPointToRay(Input.mousePosition);

现在想象一个立方体。在单击此立方体的任何位置,从单击的边缘,通过对象绘制一条线,并在另一端停止。垂直或水平方向取决于单击哪一侧,四个侧面之一,或顶部或底部。

如何确定距离(从网格的一个边缘到另一个边缘)和方向(垂直或水平)?

思想?

我到目前为止只有想法是使用碰撞检测并使用CollisionEnter作为起点,并以某种方式绘制到达网格的另一端并使用CollisionExit确定目标(或出口)点的线。然后进行一些计算以确定Enter和Exit方法之间的距离。

1 个答案:

答案 0 :(得分:3)

我能想到接近这个的唯一方法就是向另一个方向投射一条光线 ....

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
    //offset the ray, keeping it along the XZ plane of the hit
    Vector3 offsetDirection = -hit.normal;
    offsetDirection.y = 0;
    //offset a long way, minimum thickness of the object
    ray.origin = hit.point  + offsetDirection * 100;
    //point the ray back at the first hit point
    ray.direction = (hit.point - ray.origin).normalized;
    //raycast all, because there might be other objects in the way
    RaycastHit[] hits = Physics.RaycastAll(ray);
    foreach (RaycastHit h in hits)
    {
        if (h.collider == hit.collider)
        {
            h.point; //this is the point you're interested in
        }
    }
}

这会将光线偏移到新位置,以便它保留原始命中的相同XZ坐标,因此生成的端点形成一条与世界/场景Y轴垂直的线。为此,我们使用相机的Forward方向(因为我们希望距离视点更远一点)。如果我们想得到一条垂直于命中曲面的线(与曲面法线平行),我们可以使用hit.normal创建一个偏移。

您可能希望将layermask或maxdist参数放入两个光线投射方法中(因此它会检查更少的内容并且速度更快),但那就是你。

原始代码:,用于查找通过对象投射的“单个”光线的两个端点。

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
    //offset the ray along its own direction by A LOT
    //at a minimum, this would be the maximum thickness of any object we care about,
    //PLUS the distance away from the camera that it is
    ray.origin += ray.direction * 100;
    //reverse the direction of the ray so it points towards the camera
    ray.direction *= -1;
    //raycast all, because there might be other objects in the way
    RaycastHit[] hits = Physics.RaycastAll(ray);
    foreach(RaycastHit h in hits)
    {
        if(h.collider == hit.collider)
        {
            h.point; //this is the point you're interested in
        }
    }
}