Ben Rubin
Ben Rubin

Reputation: 7341

Warning when calling IsPointerOverGameObject after updating Unity; is there an alternative?

I have an InputAction callback where I am recording the position where the player clicks the screen, but only if the click is not over a UI element. Here's my code

private void OnPress(InputAction.CallbackContext context)
{
    if (!EventSystem.current.IsPointerOverGameObject())
    {
        this.pressPosition = Mouse.current.position.ReadValue();
    }
}

This has been working correctly. However, I recently updated my version of Unity, and now I'm getting this warning every time I click somewhere in my game:

Calling IsPointerOverGameObject() from within event processing (such as from InputAction callbacks) 
will not work as expected; it will query UI state from the last frame

According to the changelog, this warning was added with an update to the input system.

Is there a way to figure out whether the mouse was over the UI when the player clicks the screen without getting this warning?

Upvotes: 4

Views: 5596

Answers (3)

Lothar
Lothar

Reputation: 1

I found a solution that works for me. here: https://www.marginallyclever.com/2022/06/friday-facts-15-unity-2021-3-tips/

private MyNewInputSystem commands;
private void Update()
{
    DoNotClickUIAndGameAtSameTime();

}

private void DoNotClickUIAndGameAtSameTime()
{
    if (EventSystem.current.IsPointerOverGameObject())
    {
        commands.Commands.Disable();
    }
    else
    {
        commands.Commands.Enable();
    }
}

Disable inpit commands every time you is clicking on UI

Upvotes: 0

Alperen Şişman
Alperen Şişman

Reputation: 11

 private bool pressControl = false;
 private void Update()
 {
    if (Mouse.current.leftButton.wasPressedThisFrame)
        pressControl =!EventSystem.current.IsPointerOverGameObject(PointerInputModule.kMouseLeftId);
 }

 void selector(InputAction.CallbackContext context)
 {
    if (!pressControl) return;
    pressControl = false;

    Vector3 position = new Vector3(mausePositionEvent.ReadValue<Vector2>().x, mausePositionEvent.ReadValue<Vector2>().y, 0);
    Ray ray = Camera.main.ScreenPointToRay(position);
    RaycastHit hit;
    if (!Physics.Raycast(ray, out hit)) return;
 }

Upvotes: 1

Jorge
Jorge

Reputation: 86

how I solved it was by moving just that piece of logic to an Unity's Update function:

private void Update()
{
  if (Mouse.current.leftButton.wasPressedThisFrame)
  {
    if (EventSystem.current.IsPointerOverGameObject(PointerInputModule.kMouseLeftId))
      // was pressed on GUI
    else
      // was pressed outside GUI
  }
}

You can still keep using the inputsystem, i.e. when cancelled:

private void OnPress(InputAction.CallbackContext context)
{
  if (context.canceled)
    // Left mouse is no longer pressed. You can do something within the input system notification.
}

Upvotes: 3

Related Questions