赞
踩
按照传统的做法,EventSystem用做UI的事件处理,射线检测用做非UI碰撞的判断,但需要手动添加Collider。EventSystem使用了,GraphicRaycaster组件来检测UI元素的事件,其底层还是使用了射线来检测碰撞的。
虽然UI组件勾选Raycast Target能够按照层级关系阻挡穿透,但其阻挡的是UI组件之间的射线穿透。GraphicRaycaster的源码中有 var foundGraphics = GraphicRegistry.GetGraphicsForCanvas(canvas);
只会判断Graphic对象,这是UI元素的父类。
那么,手动的射线就会有穿透UI的问题,所以我们需要一个能判断UI元素被点击的需求,看代码封装。
/// <summary>
/// Whether touch down or mouse button down over UI GameObject.
/// </summary>
public static bool IsClickDownOverUI()
{
#if UNITY_EDITOR
if (Input.GetMouseButtonDown(0))
#else
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Began)
#endif
{
#if UNITY_EDITOR
if (EventSystem.current.IsPointerOverGameObject())
#else
if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
#endif
{
return true;
}
}
return false;
}
/// <summary>
/// Whether touch up or mouse button up over UI GameObject.
/// </summary>
public static bool IsClickUpOverUI()
{
#if UNITY_EDITOR
if (Input.GetMouseButtonUp(0))
#else
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Ended)
#endif
{
#if UNITY_EDITOR
if (EventSystem.current.IsPointerOverGameObject())
#else
if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
#endif
{
return true;
}
}
return false;
}
原理是,根据屏幕的点击,手动发射一条射线,然后获取碰撞的对象。
/// <summary>
/// Raycast a ray from touch up or mouse button up and test whether hit transform,
/// if hit transform return it or return null.
/// [isCheckHitUI] Whether check ray hit ui transform,
/// if hit ui just return null.
/// </summary>
public static Transform Raycast(bool isCheckHitUI = true)
{
#if UNITY_EDITOR
if (Input.GetMouseButtonUp(0))
{
if (isCheckHitUI)
{
if (EventSystem.current.IsPointerOverGameObject())
{
return null;
}
}
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
#else
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Ended)
{
if (isCheckHitUI)
{
if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
{
return null;
}
}
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
#endif
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
// or hit.collider.transform;
return hit.transform;
}
}
return null;
}
「老问题了,更好的实践,看后续」
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。