Unity给我们提供了IPointer一些unity事件接口。比如:IBeginDragHandler,IPointerClickHandler等。
在新建场景中创建一个canvas后,我们会发现canvas上有一个GraphicRaycaster组件。他是负责射线检测和Canvas上的UI图形的交互组件。所以我们可以使用EventSystem.current.IsPointerOverGameObject()来判断鼠标是否在UI上。
很多时候我们也会去点击3d场景里的物体,我们给3d物体加上collider后在加上一个我们自己的脚本,如test.cs.
public class Test: MonoBehaviour,IPointerDownHandler
{
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("click");
}
}
我们运行场景后发现点击物体并没有debug。是由于我们没有给摄像机中添加另一个类似GraphicRaycaster专门用来检测和3D交互的组件PhysicsRaycaster。注意这个组件需要和camera在同一个物体上。此时运行点击,会有debug。
但是,我们在在场景中运行EventSystem.current.IsPointerOverGameObject()来判断鼠标是否在UI上,当我们把鼠标放在3d物体上时,会返回true。也就是说此时这句代码来判断是否在UI上已经无效。EventSystem系统里存储的是所有raycaster返回来的信息。此时如果我们项目里有需要判断是否在UI上的需求,这是冲突的无效的。这也是我之前遇到的问题。
所以在对于3d物体的点击,我们可以自己写一个IPointer事件。或者使用OnMouseDown()等相关函数。(测试:两个相同物体在同一位置,第一次运行点击只有一个物体会被调用OnMouseDown()函数,之后无论怎么在Inspector面板调节位置顺序,都是之前的物体被调用,所以不太好控制)。总之是建议自己写一个IPointer接口以及射线发射管理系统。
如有错误,欢迎留言。一起讨论。