Android Latency Problem

Hi, I’m working on a rhythm game in Unity, but I’m finding it hard to solve android’s touch lag issues. I tested touch delay on Huawei Nova 5T with input system.

using UnityEngine;
using UnityEngine.InputSystem.EnhancedTouch;

public class Test : MonoBehaviour
{
    void Start()
    {
        Application.targetFrameRate = 60;
        EnhancedTouchSupport.Enable();
    }
    private void OnDisable()
    {
        EnhancedTouchSupport.Disable();
    }
    void Update()
    {
        var activeTouches = UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches;
        for (var i = 0; i < activeTouches.Count; ++i)
        {
            var touch = activeTouches[i];
            if (touch.began)
            {
                int lag = (int)(1000 * (Time.realtimeSinceStartup - touch.startTime));
                Debug.Log(lag);
            }
        }
    }
}

1.The first time I touch the screen, the delay is 30ms.
2.The first time I touched the screen with two fingers, one of my fingers had a 40ms delay.
3.After that, the delay will be between 10-20ms
The first time I touch the screen, and the first time I use two fingers to tap the screen, the lag suddenly increases, is there any way to avoid this sudden increase in latency.

Hi,

Can you also check FPS during the touches?

I recently fixed a problem that during touch input we were contending with java UI thread on android, which was dropping FPS and increasing latency. That should be landed in 2019.4.32f1/2020.3.20f1/2021.2.0b14 by now. That should improve FPS drops.

As per latency, IIRC our code is not doing too much buffering, so whatever Android sends our way should be propagated to managed with-in 1-2 frames. So if possible, it would be useful if you could instrument the java code directly by overriding public boolean onTouchEvent(MotionEvent event) and checking what latency android java code itself sees.

Hi, thank you for your reply.
I’ve updated Unity to 2019.4.32f1, but the problem still seems to be there. I set scripting Backend to “IL2CPP”, but the delay is still large for the first click and the first two-finger click. Since the test was done in an empty scene, the frame rate on the profiler didn’t seem to fluctuate much.

I don’t know much about this part. If possible, could you please provide some more details about instrument the java code? Thank you very much.

7623190--948163--test.png

Hi again, I’ve talked to mobile team folks, we still think the best course of action would be to try to measure device latency directly and bisecting if the problem is with the device or with input pipeline.

You can override our activity via Unity - Manual: Extend the default Unity activity
Then override _@Override public boolean onTouchEvent(MotionEvent event) { } and inside print a difference between motion event timestamp and SystemClock.uptimeMillis(); (try using mobile adb log printer package to ease reading the logs).

This should give you the same values as unity sees, if there is no abnormal latency observed there it means we have a bug in unity code somewhere that makes events stuck.

@Override public boolean onTouchEvent(MotionEvent event)
{
    if(event.getAction()== MotionEvent.ACTION_DOWN)
        Log.d("JavaTouch:", "lag:"+(android.os.SystemClock.uptimeMillis()-event.getDownTime()));
    return mUnityPlayer.injectEvent(event);
}

I tried to override onTouchEvent, but I didn’t get a log at runtime, but when I added a log to onStart, the log displayed normally.

Android’s touch delay is normally between 1 and 3 frames.The delay is still concentrated on the initial click.I also noticed that if the phone goes to sleep for a long time and then starts the app again, the delay for the first one/two finger click will be much larger, possibly over 100ms.I recorded deltaTime 10 frames before I received a click, but didn’t notice a drop in frame rate. Touch lag is not very common, and even in long tests, it’s hard to find conditions that actually trigger it.

Hi @Wanwu314 did you fix this problem? i’m facing exactly the same with Unity LTS 2021

Sadly, I still not find the way to reduce the latency, The method I’m using right now is to get the delay time after the delay occurs. I don’t know if you have used Input System before?

UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches[i].startTime;

Here is a example:
0 ms, game start
7130ms, you click the screen
7230ms, Unity receive the click, you know currently is 7230ms, You get the startTime =7130ms, so delay is 7230 - 7130=100ms
This is my understanding of startTime.
Currently, knowing how long the delay can already solved my problems. I don’t know if this way will help you.

@dmytro_at_unity has there been any effort to give the New Input System the prowess to receive input faster than frame rate, or at the polling rate of the Android OS.

Many modern Android phones have touch and button input polling and reporting faster than the visual frame rate, and these are often gaming focused Android phones. There are dozens of models of these in China, and they sell very well.

it’d be nice to target their users with Unity games that benefit from the increased responsiveness of these phones.