Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question Fastest way to read touch input on mobile

Discussion in 'Input System' started by mylastggeast, Sep 22, 2021.

  1. mylastggeast

    mylastggeast

    Joined:
    Jun 14, 2021
    Posts:
    43
    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:

    Code (CSharp):
    1. InputSystem.pollingFrequency = 240.0f;
    but I am currently reading the touches in an Update loop like this

    Code (CSharp):
    1. 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: https://docs.unity3d.com/Packages/com.unity.inputsystem@1.1/manual/Events.html but I don't understand how to get the information I need, namely .touchId, .startTime and .screenPosition

    Am I missing something?
     
  2. mylastggeast

    mylastggeast

    Joined:
    Jun 14, 2021
    Posts:
    43
    I made some progress with the following approach

    Code (CSharp):
    1. InputSystem.onEvent += (eventPtr, device) =>
    2. {
    3.             Touchscreen touchscreen = device as Touchscreen;
    4.             float startTime = (float)touchscreen.primaryTouch.startTime.ReadValue();
    5.             Vector2 position = touchscreen.primaryTouch.position.ReadValue();
    6.             int touchId = touchscreen.primaryTouch.touchId.ReadValue();
    7.             UnityEngine.InputSystem.TouchPhase phase = touchscreen.primaryTouch.phase.ReadValue();
    8. }
    but it looks like the phases are all messed up, as I get Ended before Began, what am I doing wrong?
     
  3. Digimaster

    Digimaster

    Joined:
    Aug 8, 2017
    Posts:
    7
    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:


    Code (CSharp):
    1. public void FingerProcessing(Finger finger)
    2. {
    3.    var position = finger.currentTouch.screenPosition;
    4.    var phase = finger.currentTouch.phase;
    5.    var index = finger.index;
    6.    var startTime = finger.currentTouch.startTime;
    7.  
    8.    Debug.Log($"onFingerDown: Position: {position}, phase: {phase}, index: {index}, startTime: {startTime}");
    9. }
    10.  
    11. public void AddEnhancedTouchEventListener()
    12. {
    13.    UnityEngine.InputSystem.EnhancedTouch.Touch.onFingerDown += FingerProcessing;
    14.  
    15.    UnityEngine.InputSystem.EnhancedTouch.Touch.onFingerMove += FingerProcessing;
    16.  
    17.    UnityEngine.InputSystem.EnhancedTouch.Touch.onFingerUp += FingerProcessing;
    18. }
     
    mylastggeast likes this.
  4. mylastggeast

    mylastggeast

    Joined:
    Jun 14, 2021
    Posts:
    43
    Thanks for the suggestion!
     
  5. lthaca

    lthaca

    Joined:
    Feb 23, 2021
    Posts:
    9
    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?
     
  6. tabulatouch

    tabulatouch

    Joined:
    Mar 12, 2015
    Posts:
    26
    I am interested with this too, I tried to get events independently from update framerate but have not found a reliable solution yet.
     
  7. mylastggeast

    mylastggeast

    Joined:
    Jun 14, 2021
    Posts:
    43
    I ended up sticking with the pooling from

    Code (CSharp):
    1. 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.