Unity Physics.Raycast 似乎没有正确检测到它击中的物体

Hel*_*ena 5 c# unity-game-engine raycasting

我有一个从 UnityEngine.EventSystems 实现 IDragHandler 和 IDropHandler 的游戏对象。

在 OnDrop 中,我想检查一下,这个对象是否被放置在另一个对象的前面。我正在使用 Physics.Raycast,但它仅在某些情况下返回 true。我使用屏幕点到光线作为我的光线方向,并将此变换作为 Raycast 光线的原点。

我的代码:

 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);
         }
 }
Run Code Online (Sandbox Code Playgroud)

我正在使用透视相机。当对象直接从屏幕/相机放置在对象前面时,Physics.Raycast 有时会返回 true,但“hit”包含这个,而不是后面的对象。有时它返回false。这两个结果都不是预期的,这背后有一些物体应该可以用于 Raycast。

当对象被放置在摄像机视图外围的前面对象中时,Physics.Raycast 成功找到后面的对象。

Debug 射线看起来不错,它是从我放下的对象中绘制的,向后绘制到它应该击中的对象。

Hel*_*ena 1

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

    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;
    }
Run Code Online (Sandbox Code Playgroud)

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