我使用新输入系统接收来自鼠标的输入,但我不想在任何 UI 元素上接收输入。我尝试过
EventSystem.current.IsPointerOverGameObject()
。它似乎有效,但每次收到输入时它也会发出警告。
从事件处理中(例如从 InputAction 回调)调用 IsPointerOverGameObject() 将无法按预期工作;它将从最后一帧查询 UI 状态 UnityEngine.EventSystems.EventSystem:IsPointerOverGameObject () ...
这是我的代码:
private void OnEnable()
{
mouseClick.Enable();
mouseClick.performed += MousePressed;
}
private void OnDisable()
{
mouseClick.performed -= MousePressed;
mouseClick.Disable();
}
private void MousePressed(InputAction.CallbackContext context)
{
if (EventSystem.current.IsPointerOverGameObject()) return;
Ray ray = _playerCam.ScreenPointToRay(Mouse.current.position.ReadValue());
RaycastHit hit;
...
}
我该怎么办?
private void MousePressed(InputAction.CallbackContext context)
{
PointerEventData eventData = new(EventSystem.current)
{
position = context.ReadValue<Vector2>()
};
List<RaycastResult> results = new();
EventSystem.current.RaycastAll(eventData, results);
if (results.Count > 0)
return;
// ...
}
如果你想检查是否点击了任何
UI
对象,可以使用EventSystem
来实现。
首先我们从
PointerEventData
current
中获取 EventSystem
并将其 PointerEventData.position
分配给 context.ReadValue<Vector2>()
。我们不必转换它,因为 position
采用 screen space
中的坐标,这也是返回值的空间。也可以这样实现。任何对您来说更具可读性的内容。
Vector2 contextPos = context.ReadValue<Vector2>();
PointerEventData eventData = new(EventSystem.current);
eventData.position = contextPos;
然后我们调用之前设置的
EventSystem.current.RaycastAll
的PointerEventData
方法并将List<RaycastResult>
存储在我们创建的results
中。此方法获取每个将 UI Object
设置为 Graphic.raycastTarget
的 true
。否则这些对象甚至不会响应用户的点击。
如果列表不为空,我们就会破坏该方法,因为至少找到了一个
UI
。现在,如果您想检查这个UI
,例如a Button
,您在评论中提到过,您可以枚举其项目并检查它。
foreach (RaycastResult result in results)
{
if (result.gameObject.GetComponent<Button>())
return;
}
此外,您可以通过标签找到您的
UI
。
foreach (RaycastResult result in results)
{
if (result.gameObject.CompareTag("MyButton"))
return;
}