How to keep time reference during mobile window switch? (Unity)

Viewed 107

I have a game where I have a queue matchup system. I would like to show the player how long they been in the current queue. It works well, until the player presses the menu/app overview button on their phone, which basically freezes the timer, and it only continues counting when the player switches back to full screen mode on their phone.
I tried looking for an app lifecycle method (somewhat like onApplicationPause, but it didn't work for me)
I also tried syncing the time by saving it in the db and then loading from the database actually, but Firebase puts on some delay, so it won't be exact. How could I solve this, so it will keep counting when the user presses their app overview/menu button on their phone?

For now, I have this code which counts the user's queue time:

private void Update() {
    if(startedCounting) {
        timer += Time.deltaTime;
        int seconds = Mathf.FloorToInt(timer % 60);
        int minutes = Mathf.FloorToInt(timer / 60);
        queueStatusText.text = "You are in the queue\n"
                               + string.Format("{0:00}:{1:00}", minutes, seconds);
    }
}
1 Answers

There are different aproaches, some using static class or singleton pattern. It is better to not update this time variable each time on Update() as it takes the computation time each update (if you don't need this time for anything else). Also user doesn't need to have exact time by frames so you can avoid things like adding Time.deltaTime.

I'll show you example with static class, it can hold this information. Also note that this script is only added as C# file, but you don't attach it to any GameObject :

public static class QueueTimerInformation //It is not inheriting from MonoBehavior!
{
    private static DateTime dt;
    private static bool isRunning = false;

    //Save current DateTime when user did the action
    public static void Start()
    {
        if(!isRunning)
        {
            dt = DateTime.Now;
            isRunning = true;
        }
    }

    public static void Reset()
    {
        isRunning = false;
    }

    // This gets the actual time in String value
    // Usually it is better to return just `elapsedTime` and format it later
    public static string GetTimeElapsed()
    {
        if(!isRunning) return "00:00"; //Not running, return some default

        var elapsedTime = (DateTime.Now - dt);
        return $"{elapsedTime:mm\\:ss}";
    }
}

Usage

//On 1st time enter lobby
QueueTimerInformation.Start();

//In update method
var result = QueueTimerInformation.GetTimeElapsed();
Related