Filtering UI Toolkit related touches

Hello.
I’ve recently started implementing touch support for our project and as we are already using the New Input System I decided to go with the EnhancedTouchSupport API.
Our project is really UI-heavy, and we use EventSystem.current.IsPointerOverGameObject() to filter out mouse inputs that are currently done over UI elements and do not pass them to the game.
We have a simple update method:

public void Update()
{
   _isTouchOverUI = EventSystem.current.IsPointerOverGameObject();
}

However, this does not work for the touch input.
It technically does, however, if I subscribe to events like Touch.onFingerDown
and Touch.onFingerMove and use the _isTouchOverUI there it’s still not “true” for one finger down event and one move event, so they are still passed down to the game and this causes issues for us.
Is there any way to check if touch started over the UI during the current input event?

Thanks in advance.

This is really a problem with the InputSystem’s IsPointerOverGameObject method.

According to this documentation Class InputSystemUIInputModule | Input System | 1.11.2, IsPointerOverGameObject can’t be used immediately when the input is received, as is the case in your code:

Be aware that this method relies on state set up during UI event processing that happens in EventSystem.Update , that is, as part of MonoBehaviour updates. This step happens after input processing. Thus, calling this method earlier than that in the frame will make it poll state from last frame.

I’m not too sure how feasible it is for you to delay all the rest of your game logic to wait for the IsPointerOverGameObject method to be ready. Alternatively, you can poll UI Toolkit’s panel directly with the touch position using panel.Pick(RuntimePanelUtils.ScreenToPanel(panel, touchPosition)).

1 Like

Thanks for the answer.
That’s too bad there’s no “direct” alternative to IsPointerOverGameObject with such an easy-to-use API.
I was thinking about queuing up touch input events and then sending them to the game logic in Update or FixedUpdate after the IsPointerOverGameObject check which should solve my issue.
However, if I use Update this will make my input framerate dependent, which I would prefer not to do. And if use FixedUpdate I might still not get the correct IsPointerOverGameObject value in low framerate scenarios.
Will FixedUpdate behave like I expect it to, meaning it can still result in IsPointerOverGameObject being false when running at a low framerate?

I don’t think you can use FixedUpdate like that unless maybe if you change your input to also be updated on FixedUpdate? At this point you might have better luck asking on the Input forum, this seems more like InputSystem-package specific behavior.