[Solved-ish] Touch phase "Began" across multible frames until moved (EnhancedTouch)

I have the following code, and I’m getting odd behavior regarding the Began phase. Sometimes it won’t be called (goes straight to Moved), other times it will be repeatedly called until I move my mouse (using Touch simulation). Stationary will only be called after the first move. It sometimes behaves as expected, however. In another script (basically the same except for some movement stuff), the “Began” phase burst will be about equal to the times it skipped.

My test code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem.EnhancedTouch;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;

public class TestInputs : MonoBehaviour
{
    private void Awake()
    {
        EnhancedTouchSupport.Enable();
    }

    void Update()
    {
        if (Touch.activeFingers.Count == 1)
        {
            Touch activeTouch = Touch.activeFingers[0].currentTouch;

            if (activeTouch.phase == UnityEngine.InputSystem.TouchPhase.Began)
            {
                Debug.Log("Touch started: " + Time.frameCount);
            }

            if (activeTouch.phase == UnityEngine.InputSystem.TouchPhase.Moved || activeTouch.phase == UnityEngine.InputSystem.TouchPhase.Stationary)
            {
                Debug.Log("Touch moved/stationary: " + Time.frameCount);
            }

            if (activeTouch.phase == UnityEngine.InputSystem.TouchPhase.Ended)
            {
                Debug.Log("Touch ended: " + Time.frameCount);
            }
        }
    }
}

Console output looks like this:

Touch started: 226

Touch started: 227

Touch started: 228

Touch started: 229

Touch ended: 230

I could just write my own “Began” check, but there’s nothing to learn in doing that :). From my understanding EnhancedTouch is the one that should work with update() polling, but is there more I need to do to get that working?

Thank you!

Used this tutorial: Tutorial: Implementing touch with Input System's Enhanced Touch API
–Edit in case anyone has this issue:
I replaced Touch.activeFingers[0].currentTouch with just Touch.activeTouches[0] to get the expected behavior. If anyone whats going on here I’d appreciate it!

So I added activeTouch.startTime to the began debug log, and they are all at the same startTime despite registering “Began” perpetually across frames (or until Ended or Moved).

Touch started: 4 vs 3.64670062893674
...(many lines later)
Touch started: 20 vs 3.64670062893674

Touch started: 21 vs 3.64670062893674

Touch started: 22 vs 3.64670062893674

It will do this forever btw, it doesn’t appear to be a timing/polling issue where phase == Began for a few microseconds before it switches phase.

-Update
So I split the moved/stationary checks, and activeTouch.phase never is stationary even when it should be. It appears to be an issue where the touch.phase never actually changes unless the position is actually changing? I can’t build to check on my device atm, but is this possibly to do with the touch simulation? Otherwise is there an issue about how the current touch is being polled? It should occur every Update() right?

Console output where the phase is reporting as Moved even though there is no position changes:

Touch moved 270 Pos: (1008.0, 743.0)

Touch moved 271 Pos: (1008.0, 743.0)

Touch moved 272 Pos: (1008.0, 743.0)

Touch moved 273 Pos: (1008.0, 743.0)

So I replaced Touch.activeFingers[0].currentTouch with just Touch.activeTouches[0] and now everything is behaving as expected. I don’t know why currentTouch isn’t working (and never is stationary) for this especially given that the tutorial seems to indicate it should work fine. If anyone has an explanation I’d appreciate it!

7 Likes

Thank you for this!! I thought I was losing it and this totally fixed it :slight_smile:

1 Like

Thank you!

Have the same issue here in 2024, no information whatsoever on how to fix this. The two touches even have the same ID and yet are not equal.