Home > database >  Detect long touch in Unity 3D
Detect long touch in Unity 3D

Time:04-09

I'm trying to detect long touch on the screen by using Time.time or Time.deltatime, but nothing works. It should turn out like this: after beginning TouchPhase.Stationary (or Began) timer should goes on, then after TouchPhase.Ended timer can be reset to 0. But here is condition that checks, if I held the button on the sensor less than 0.5 sec - do something.

Problems:

  1. Time.Deltatime for some reason it does not add up to a variable for each iteration, but constantly assigns a new value equal to the time of the last frame, somewhere around 0.02-0.1

  2. Time.time constantly adds a value to the variable, when subtracting the time of pressing the screen and the vacation time, the variable that should be reset to zero, but with each iteration of actions, the value for some reason cannot vary from 0.0 - 0.05, the timer for some reason constantly sums up the value and the variable constantly increases

My ask: how can I track how many seconds my finger was on the screen?

void TapOrLongTounch()
{
    float pressTime = 0;
    float endPressTime = 0;
    if (Input.touchCount > 0)
    {
        Touch touch = Input.GetTouch(0);
        if (touch.phase == TouchPhase.Stationary)
        {
            pressTime  = Time.time;
        }

        if (touch.phase == TouchPhase.Ended)
        {
            endPressTime = Time.time - pressTime;

            if (endPressTime < 0.5f)
            {
                //Do something;
            }
            endPressTime = 0;
        }
    }
}

CodePudding user response:

First of all Time.time is

This is the time in seconds since the start of the application [...].

What you are doing is basically exponentially adding more and more time every frame.

→ What you rather want to count is the Time.deltaTime

The interval in seconds from the last frame to the current one [...].

like

if (touch.phase == TouchPhase.Stationary)
{
    pressTime  = Time.deltaTime;
}

so that pressTime results in the total amount of time in seconds the touch was stationary.

BUT you also have it as a method variable so it continuously starts from 0 anyway!

→ You rather want to have a class field for it!


Then further the

if (touch.phase == TouchPhase.Ended)
{
    endPressTime = Time.time - pressTime;
    ...
    

makes no sense / is pretty redundant. The pressTime already is the total time in seconds the touch was stationary!


In general I would rather use a switch-case and do e.g.

float pressTime = 0;

void TapOrLongTounch()
{
    if (Input.touchCount <= 0) return;
    
    var touch = Input.GetTouch(0);

    switch(touch.phase)
    {
        // Maybe you also want to reset when the touch was moved?
        //case TouchPhase.Moved:
        case TouchPhase.Began:
            pressTime = 0;
            break;

        case TouchPhase.Stationary:
            pressTime  = Time.deltaTime;
            break;

        case TouchPhase.Ended:
        case TouchPhase.Canceled:
            if (pressTime < 0.5f)
            {
                //Do something;
            }
            pressTime = 0;
            break;
    }
}
  • Related