解决同时响应UI和3D物体事件
传统使用OnMouseDown回调会同时响应UI与3D物体事件,可使3D物体继承IPointerClickHandler实现OnPointerClick方法避免穿透(使用此方法需要在摄像机上挂Physics Raycaster脚本)
public class ModelClickEvent : MonoBehaviour,IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("Click " + gameObject.name);
}
}
若此时需要穿透,则可以在UI上这样写来穿透
public class UIClickMessenger : MonoBehaviour,IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("Click "+gameObject.name);
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventData, results);
foreach (var result in results)
{
Debug.Log("raycast:" + result.gameObject.name);
if (!gameObject.Equals(result.gameObject))
{
ExecuteEvents.Execute(result.gameObject, eventData, ExecuteEvents.pointerClickHandler);
}
}
}
}
识别当前点击点为UI区域还是非UI区域
GraphicRaycaster _raycaster;
private void Start()
{
_raycaster = FindObjectOfType<GraphicRaycaster>();
}
bool isUI()
{
PointerEventData point = new PointerEventData(EventSystem.current);
point.position = Input.mousePosition;
point.pressPosition = Input.mousePosition;
List<RaycastResult> result = new List<RaycastResult>();
_raycaster.Raycast(point, result);
return result.Count > 0;
}
注意:还可以使用EventSystem.current.IsPointerOverGameObject()来鉴别,但是如若使用上述方法,即实现IPointerClickHandler接口,则该3D物体在点击时同样会返回True.