Search code examples
c#androidunity-game-enginetimergame-engine

Time.unscaledDeltaTime still counting even when app is in background


I just use a generic code to count how long the player has been playing in the update function:

float time;

void Update()
{
    time += Time.unscaledDeltaTime;
}

Here is the problem:

When I press the home button on my android device or browse past applications the timer still counts. So if I wait a while in home or in other apps screen and come back to the game, the timer includes time even when I have been out of the app. The game state stays exactly how it was before but only the timer changes.

What could be the reason and how can I prevent the timer from counting when the application does not have focus?


Solution

  • A normal value from Time.unscaledDeltaTime is usually around 0.01687395. When Time.unscaledDeltaTime is used, it is still adding up in the background when you shift focus out of the app. Once you return back to the app, the value of Time.unscaledDeltaTime will be the x seconds you were out of the app.

    For example, if you shift focus out of the app for 15 seconds then return back, the output of Time.unscaledDeltaTime will be 15 in the first frame then jump back to around 0.01687395. The Time.deltaTime variable does not have this problem but it is not an option too since changing Time.timeScale affects it.

    The solution is to use OnApplicationFocus and OnApplicationPause to detect when the application is running again then skip adding Time.unscaledDeltaTime in the first frame as that first frame is when Time.unscaledDeltaTime is really the x seconds you were out of the app.

    Here is a working solution:

    public Text text;
    float currentTime = 0;
    private bool skipFrame = false;
    
    void Update()
    {
        //Add only when we don't need to skip frame
        if (!skipFrame)
        {
            currentTime += Time.unscaledDeltaTime;
            text.text = currentTime.ToString();
        }
    
        //We need to skip frame. Don't use Time.unscaledDeltaTime this frame
        else
        {
            skipFrame = false;
            Debug.LogWarning("Filtered accumulated Time when Paused: " + Time.unscaledDeltaTime);
        }
    }
    
    
    void OnApplicationFocus(bool hasFocus)
    {
        //Enable skipFrame when focoused in app
        if (hasFocus)
        {
            //Debug.Log("Has focus");
            skipFrame = true;
        }
    }
    
    void OnApplicationPause(bool pauseStatus)
    {
        //Enable skipFrame when coming back from exiting app
        if (!pauseStatus)
        {
            //Debug.Log("UnPaused");
            skipFrame = true;
        }
    }