Search Unity

Question TouchPhase.Began doesn't always happen.

Discussion in 'Input System' started by petey, Oct 11, 2020.

  1. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Hi all,

    Just working with the new input system and I've found some issues with touch input. For some reason TouchPhase.Began doesn't always happen, is there some reason why that would happen?
    Maybe the update?

    Code (CSharp):
    1.     private void Awake()
    2.     {
    3.         UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.Enable();
    4.     }
    5.  
    6.     public void Update()
    7.     {
    8.         foreach (var finger in UnityEngine.InputSystem.EnhancedTouch.Touch.activeFingers)
    9.         {
    10.             Debug.Log( finger.currentTouch.phase+" <<");
    11.             if (finger.currentTouch.phase ==  UnityEngine.InputSystem.TouchPhase.Began)
    12.             {
    13.                 Beep();
    14.             }
    15.         }
    16.     }
    Also for some weird reason, if I build to the iPad TouchPhase.Began fires constantly during a press.

    Oh I should say this is on input system 1.0.0 and Unity 2019.4
     
    Last edited: Oct 11, 2020
  2. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Well it looks like the began phase is unreliable even though the touch count changes.
    I moved my 'Began' code into touch phase - Began, Moved and Stationary with a bunch of checks to make sure it only runs once before any 'moved' stuff. Bit of a shame it feels pretty hacky.
     
  3. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Should be fixed as of 1.1-preview.1.
     
    petey likes this.
  4. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Ahh that's working great! Thanks :)
     
  5. dpotuznik

    dpotuznik

    Joined:
    Jan 18, 2018
    Posts:
    17
    Hi,

    I try the same code from the first post.


    i have the same issue the began work only about 8/10 time and i have installed the 1.1.preview 3

    do you found a workaround?
    or i need to setup differently? fixeupdate ... ?

    thank you for your help
    Best Regards
    Daniel

    Unity 2020.2.3f1

    hardware:
    IIyama 27355msc (27") 10 touch
    windows 10 V:2004
    intel I7 9th gen 9750H / 32Gb
    rtx 2080 Qmax
     
  6. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Hi Daniel, would you mind filing a ticket with the bug reporter (Help >> Report a Bug... in the Unity editor)? Sounds like there's potentially a separate thing with Windows touch input that needs looking at.
     
  7. TrueNoob141

    TrueNoob141

    Joined:
    Sep 18, 2019
    Posts:
    30
    Same. Some touches don't trigger Began, but Input Debugger show Began phase.

    Device: LG G2
    Unity: 2020.2.1f1, 2020.3.12f1
    Package: Input System 1.1.0-preview.3 (LTS doesn't support newer package)

    Code (CSharp):
    1. private void Update()
    2. {
    3.     var touch = Touchscreen.current?.primaryTouch;
    4.     if (touch == null)
    5.         return;
    6.  
    7.     var id = touch.touchId.ReadValue();
    8.     var phase = touch.phase.ReadValue();
    9.  
    10.     // Missing (phase == TouchPhase.Began) for some swipes
    11.     Debug.LogWarning($"Touch {id}, Phase {phase}");
    12. }
     
  8. TrueNoob141

    TrueNoob141

    Joined:
    Sep 18, 2019
    Posts:
    30
    How (I didn't touching anything)?
    2021-07-02-14-29-32-ouwBy.png
     
  9. mylastggeast

    mylastggeast

    Joined:
    Jun 14, 2021
    Posts:
    41
    I don't know if this might help in your case, but I believe that is not recommended to use the Touchscreen API in an Update for pooling, Unity recommends using the EnanchedTouch for that use case: https://forum.unity.com/threads/touchscreen-reporting-incorrect-touchphase.869086/

    For what it's worth, I stopped having the TouchBegan issue after updating to preview5!
     
  10. Kogar

    Kogar

    Joined:
    Jun 27, 2013
    Posts:
    80
    For me the bug seems to still be happening for Version 1.1.1 (- September 09, 2021) and Unity 2021.1.21f1.3059 Personal. (Just trying to make a simple multitouch tester as a start)
    Same code for touchphase detection like in the thread start. Touchphase.Began most times but not always run in the Update() loop, but touchcount correctly detected.
    Running my test on redmi k20 miui 12.5.1 android 11.

    Double checked with https://play.google.com/store/apps/details?id=com.the511plus.MultiTouchTester that it is not some device error. Also i ignore launcher gestures. (MIUI three finger [swipe] for screenshots as an example)

    Most times Touchphase.Began seems to have not fired when finger quickly in succession are touching.
    Maybe too fast for Update() polling? Could the touchphase of late finger at end of one Update() loop get overwritten by the start of the next Update() loop without firing?
     
  11. Kogar

    Kogar

    Joined:
    Jun 27, 2013
    Posts:
    80
    Have looked at https://docs.unity3d.com/Packages/com.unity.inputsystem@1.1/manual/Touch.html where the bug is even commented as a Note.

    Would be nice to update the example https://docs.unity3d.com/Packages/c...ystem.EnhancedTouch.EnhancedTouchSupport.html to
    reflect the comment and show an event driven example that is decoupled from Update() polling.

    I have adapted the example from
    https://forum.unity.com/threads/enhancedtouch-in-editor-not-recognising-touch-ended-phase.874204/
    where functions are coupled to the events.

    protected void OnEnable()
    {
    EnhancedTouchSupport.Enable();

    Touch.onFingerDown += Touch_onFingerDown;
    Touch.onFingerUp += Touch_onFingerUp;
    Touch.onFingerMove += Touch_onFingerMove;
    }

    protected void OnDisable()
    {
    EnhancedTouchSupport.Disable();

    Touch.onFingerDown -= Touch_onFingerDown;
    Touch.onFingerUp -= Touch_onFingerUp;
    Touch.onFingerMove -= Touch_onFingerMove;
    }

    private void Touch_onFingerDown(Finger latestFinger)
    {
    //use only the currently changed latestFinger
    //or if you still need to process all fingers can still use the same function as in Update()
    foreach (Finger finger in Touch.activeFingers)
    {
    }
    }

    //same for the other two functions Touch_onFingerUp(), Touch_onFingerMove()


    Now finger seems to always be correctly detected
     
    ABCodeworld and AmalexiM like this.
  12. synysterkillable

    synysterkillable

    Joined:
    Nov 12, 2019
    Posts:
    1
    hi, i found a hackie way around this using a bool and a timer to reset, check out below.

    in - else if (Input.touchCount <= 0 && hasShotSingle) i reset the touch object to default values, this resets the touch values manually, so far no issues.

    touch = default;

    Code (CSharp):
    1. if(canShoot)
    2.         {
    3.             if (justShotSingle)
    4.             {
    5.                 singleShotCounter -= Time.deltaTime;
    6.                 if (singleShotCounter <= 0)
    7.                 {
    8.                     ShootNow = true;
    9.                     justShotSingle = false;
    10.                     singleShotCounter = timeBetweenShots;
    11.                 }
    12.             }
    13.             if (Input.touchCount > 0)
    14.             {
    15.                 touch = Input.GetTouch(0);
    16.             }
    17.             else if (Input.touchCount <= 0 && hasShotSingle)
    18.             {
    19.                 touch = default;
    20.                 hasShotSingle = false;
    21.                 justShotSingle = true;
    22.             }
    23.  
    24.             if (touch.phase > 0)
    25.             {
    26.                 if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved)
    27.                 {
    28.                     shotCounter -= Time.deltaTime;
    29.                     if (shotCounter <= 0)
    30.                     {
    31.                         shotOne = psPool.GetBullets();
    32.  
    33.                         shotOne.transform.position = shotPointL.position;
    34.                         shotOne.transform.rotation = shotPointL.rotation;
    35.  
    36.                         shotOne.gameObject.SetActive(true);
    37.  
    38.                         shotTwo = psPool.GetBullets();
    39.  
    40.                         shotTwo.transform.position = shotPointR.position;
    41.                         shotTwo.transform.rotation = shotPointR.rotation;
    42.  
    43.                         shotTwo.gameObject.SetActive(true);
    44.  
    45.                         shotOne = default;
    46.                         shotTwo = default;
    47.  
    48.                         shotCounter = timeBetweenShots;
    49.                         //hasShotSingle = true;
    50.                     }
    51.                 }
    52.                 if (ShootNow)
    53.                 {
    54.                     shotOne = psPool.GetBullets();
    55.  
    56.                     shotOne.transform.position = shotPointL.position;
    57.                     shotOne.transform.rotation = shotPointL.rotation;
    58.  
    59.                     shotOne.gameObject.SetActive(true);
    60.  
    61.                     shotTwo = psPool.GetBullets();
    62.  
    63.                     shotTwo.transform.position = shotPointR.position;
    64.                     shotTwo.transform.rotation = shotPointR.rotation;
    65.  
    66.                     shotTwo.gameObject.SetActive(true);
    67.  
    68.                     shotOne = default;
    69.                     shotTwo = default;
    70.  
    71.                     shotCounter = timeBetweenShots;
    72.                     singleShotCounter = timeBetweenShots;
    73.                     ShootNow = false;
    74.                     hasShotSingle = true;
    75.                     //justShotSingle = true;
    76.                     //hasShotSingle = true;
    77.                 }
    78.             }
    79.         }