2017-01-16 407 views
3

我有一个GameObject,它实现了UnityEngine.EventSystems中的IDragHandler和IDropHandler。Unity Physics.Raycast似乎没有正确地检测到它碰到的对象

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

我使用透视相机。当物体从屏幕/摄像机直接向前丢弃时,Physics.Raycast有时会返回true,但“hit”包含这个,而不是这个背后的对象。有时它返回false。这两个结果都不是预期的,有这样的背后的东西应该是可能的Raycast。

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

调试光线看起来很好,它从我放下的物体上,倒退到它应该击中的物体上。

+0

注意:如果我不使用screenRay设置thisToObjectBehind = newRay(transform.position,transform.forward * -1),Raycast会成功,所以碰撞器应该没有任何问题。但是,我不想限制自己不得不面对相机。 – Helena

+0

什么是成功和失败时的eventData值? – Bijan

+0

你不需要LayerMask吗? – Maakep

回答

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

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

+0

不要用Unity的API捕捉异常。只有使用C#IO才能做到这一点。您不必要地让代码变慢,具体取决于您将代码附加到多少个GameObjects。只需做一个空检查。 – Programmer

+0

终于尝试了,没有抓住,就像一样糟糕?我只是想确保无论发生什么事情,我都会将游戏对象移回预先设置的图层,以避免在被调用后的怪异行为。 – Helena

+0

[JIT不对'protected'/'try'块执行优化](http://stackoverflow.com/a/1350299/3785314) – Programmer

相关问题