Fastest way to read touch input on mobile

Hello everyone!
I am developing a game for mobile (iOS / Android) and I need to process the input from the touch as quickly as possible. So far I have increased the polling frequency:

InputSystem.pollingFrequency = 240.0f;

but I am currently reading the touches in an Update loop like this

foreach (UnityEngine.InputSystem.EnhancedTouch.Touch touch in UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches)

When I confront touch.startime of the touch in the loop with Time.realtimeSinceStartup the difference can be quite significant, and also frame-dependent, meaning that a device that runs at 120 fps will basically get double the precision of a device at 60 fps.

I then thought of listening to input events instead of polling the touch buffer in an Update, like suggested here: Input events | Input System | 1.1.1 but I don’t understand how to get the information I need, namely .touchId, .startTime and .screenPosition

Am I missing something?

I made some progress with the following approach

InputSystem.onEvent += (eventPtr, device) =>
{
            Touchscreen touchscreen = device as Touchscreen;
            float startTime = (float)touchscreen.primaryTouch.startTime.ReadValue();
            Vector2 position = touchscreen.primaryTouch.position.ReadValue();
            int touchId = touchscreen.primaryTouch.touchId.ReadValue();
            UnityEngine.InputSystem.TouchPhase phase = touchscreen.primaryTouch.phase.ReadValue();
}

but it looks like the phases are all messed up, as I get Ended before Began, what am I doing wrong?

1 Like

With this approach you don’t use the recommended EnhancedTouch class anymore. However, it is quite easy to implement it and similar to what you have done above:

public void FingerProcessing(Finger finger)
{
   var position = finger.currentTouch.screenPosition;
   var phase = finger.currentTouch.phase;
   var index = finger.index;
   var startTime = finger.currentTouch.startTime;

   Debug.Log($"onFingerDown: Position: {position}, phase: {phase}, index: {index}, startTime: {startTime}");
}

public void AddEnhancedTouchEventListener()
{
   UnityEngine.InputSystem.EnhancedTouch.Touch.onFingerDown += FingerProcessing;

   UnityEngine.InputSystem.EnhancedTouch.Touch.onFingerMove += FingerProcessing;

   UnityEngine.InputSystem.EnhancedTouch.Touch.onFingerUp += FingerProcessing;
}
1 Like

Thanks for the suggestion!

Apologies for grave digging but I’m curious how this implementation worked out for you. I recently switched to the new input system and began polling touch inputs with the EnhancedTouch API and I’m blown away by how much more responsive and consistent the input detection is compared to the old input system. Now, curiosity has gotten the best of me and I’m wondering if low-level event listening is worth the headache if it delivers better touch performance than polling. Which solution did you end up going with?

I am interested with this too, I tried to get events independently from update framerate but have not found a reliable solution yet.

I ended up sticking with the pooling from

UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches

I can use touch.startTime to get a precise timestamp of the touch and compensate gameplay logic in the Update later since the visuals will only ever update on the next frame anyway. This way I get a consistent and predictable flow, which would not be possible with events probably.