UnityRef is currently in early development. Some features may be incomplete and/or not functioning.

UNITYREF

Your Pit Stop For Solving ANYTHING in Unity

ui

[UI Toolkit] Fix Mobile Touch Movement with Pointer Capture

Solution

ui toolkitmobile developmentinput systemuser experience

Unity 2021.3.x - Unity 6.3.x

Published Sun, May 10

Issue

 Touch input on mobile devices often fails to trigger PointerMoveEvent or PointerDownEvent for draggable elements when using the New Input System and UI Toolkit. While mouse interactions in the Editor function correctly, touch movement is frequently ignored once the finger leaves the initial boundaries of your visual element, causing interrupted dragging behavior.

Explanation

The default behavior of PointerMoveEvent for touch input in the UI Toolkit is to only fire while the touch remains within the original bounds of your visual element. This differs significantly from mouse input, which often maintains an active state more loosely. This limitation prevents smooth dragging on mobile devices because a fast or wide gesture often exceeds the initial hit-box of the element.

To enable reliable dragging, you must utilize the pointer capture system. This programmatically locks the pointerId to your visual element, ensuring that all subsequent movement and release events are routed to it regardless of the current touch position.

  1. Within the PointerDownEvent callback, invoke CapturePointer on your visual element using the pointerId from the event arguments.
  2. During the PointerMoveEvent, verify the element still has focus by checking HasPointerCapture with the pointerId before applying translation logic.
  3. Within the PointerUpEvent callback, invoke ReleasePointer to free the pointerId and allow other elements to receive input.

Additional Tips

  • Listen for PointerCaptureOutEvent to handle cases where the system cancels the touch (e.g., an incoming phone call or OS gesture).
  • Ensure your visual element has a usageHints set to UsageHints.DynamicTransform if it moves frequently to optimize performance.
  • Verify that the pickingMode property of your visual element is set to PickingMode.Position so it can intercept pointer events.

TL;DR

For consistent touch interaction, explicitly manage pointer state by calling CapturePointer on your visual element during the PointerDownEvent. This ensures the pointerId is tracked even when movement occurs outside the element bounds.


Related Posts Haven't quite found a solution to your problem? We think these posts might help you.

Content inspired by a Unity discussion post.