关于c#:Unity Physics.Raycast似乎没有正确检测它击中的对象

Unity Physics.Raycast does not seem to properly detect object it hit

我有一个从UnityEngine.EventSystems实现idragHandler和idrophandler的GameObject。

在OnDrop中,我想检查一下,这个对象是否被放在另一个对象前面。我用的是物理。光线投射,但在某些情况下它只能返回真值。我使用屏幕点对射线作为光线的方向,而这个变换作为光线投射的光线的原点。

我的代码:

1
2
3
4
5
6
7
8
9
10
11
 public void OnDrop(PointerEventData eventData)
 {
         var screenRay = Camera.main.ScreenPointToRay(new Vector3(eventData.position.x, eventData.position.y, 0.0f));
         var thisToObjectBehind = new Ray(transform.position, screenRay.direction);
         Debug.DrawRay(thisToObjectBehind.origin, thisToObjectBehind.direction, Color.yellow, 20.0f, false);
         RaycastHit hit;
         if (Physics.Raycast(thisToObjectBehind, out hit))
         {
             Debug.LogFormat("Dropped in front of {0}!", hit.transform);
         }
 }

我用的是透视照相机。当物体直接从屏幕/照相机前落在物体前面时,物理。光线投射有时返回真值,但"命中"包含这个,而不是这个后面的物体。有时它返回错误。这两个结果都不是预期的结果,后面的对象应该可以进行光线投射。

当物体落在相机视图外围的物体前面时,物理。光线投射成功地找到了后面的物体。

调试光线看起来很好,它是从我丢弃的对象中提取的,向后到它应该击中的对象。


临时放置在IgnoreRayCast层中的对象解决了我的问题。这也意味着我可以跳到将光线的原点设置为transform.position。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    public void OnDrop(PointerEventData eventData)
    {
        // Save the current layer the dropped object is in,
        // and then temporarily place the object in the IgnoreRaycast layer to avoid hitting self with Raycast.
        int oldLayer = gameObject.layer;
        gameObject.layer = 2;

        var screenRay = Camera.main.ScreenPointToRay(new Vector3(eventData.position.x, eventData.position.y, 0.0f));
        RaycastHit hit;
        if (Physics.Raycast(screenRay, out hit))
        {
            Debug.LogFormat("Dropped in front of {0}!", hit.transform);
        }

        // Reset the object's layer to the layer it was in before the drop.
        gameObject.layer = oldLayer;
    }

编辑:由于性能原因,从代码段中删除了try/finally块。