Dennis Liu
Dennis Liu

Reputation: 303

How to continue count down timer when game is closed?

I want to make a timer that resets a merchant's item price and quantity.

Like many android games, there are timers that continue to go down when not playing the game. When you are not playing the game, the timer should continue to countdown. How to keep the count down timer going when the game is closed?

Below is my countdown timer

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class margaretSellTimer : MonoBehaviour {
    public Text TimerText;
    public string dy;
    public float days;
    public float Hours;
    public float Minutes;
    public float Seconds;

    initMerchantMargaret initMerchants;
    player Player;

    // Use this for initialization
    void Start () {
        initMerchants = GameObject.FindGameObjectWithTag ("initMerchant").GetComponent<initMerchantMargaret> ();
        Player = GameObject.FindGameObjectWithTag ("player").GetComponent<player> ();
        StartCoroutine(Wait());

    }

    // Update is called once per frame
    void Update () {
        if (days == 1) {
            dy = "day ";
        } else if (days > 1) {
            dy = "days ";
        } else {
            dy = "day ";
        }

        if(Seconds < 10)
        {
            TimerText.text = (days + " " + dy + Hours + ":" + Minutes + ":0" + Seconds);
        }
        if(Seconds > 9)
        {
            TimerText.text = (days + " " + dy + Hours + ":" + Minutes + ":" + Seconds);
        }


    }

    public void CountDown()
    {
        if(Seconds <= 0) {
            if(Minutes > 0) {
                MinusMinute();
                Seconds = 60;
            }
        }
        if (Minutes <= 0) {
            if(Hours > 0) {
                MinusHours();
                Minutes = 59;
                Seconds = 60;
            }
        }

        if (Hours <= 0) {
            if(days > 0) {
                MinusDays();
                Hours = 23;
                Minutes = 59;
                Seconds = 60;
            }
        }

        if(Minutes >= 0)
        {
            MinusSeconds();
        }

        if(Hours <= 0 && Minutes <= 0 && Seconds <= 0 && days <= 0)
        {
            StopTimer();
        }
        else
        {
            Start ();
        }

    }

    public void MinusDays() {
        days -= 1;
    }

    public void MinusHours() {
        Hours -= 1;
    }

    public void MinusMinute() {
        Minutes -= 1;
    }

    public void MinusSeconds() {
        Seconds -= 1;
    }

    public IEnumerator Wait() {
        yield return new WaitForSeconds(1);
        CountDown();
    }

    public void StopTimer() {
        Seconds = 5;
        Minutes = 0;
        Hours = 0;
        days = 0;

        Player.margaretItemSell.Clear ();
        Player.productMargaretSell.Clear ();
        Player.productSellMargaret.Clear ();

        initMerchants.margaretSell ();

        Start ();
    }
}

Thanks.

Upvotes: 0

Views: 1910

Answers (3)

Umair M
Umair M

Reputation: 10720

To get Days, Hours, Minutes and Seconds from elapsedSeconds, you can use TimeSpane.

Like this:

TimeSpan interval = TimeSpan.FromSeconds(elapsedSeconds);
days = interval.Days;
hours = interval.Hours;
minutes = interval.Minutes; // etc

Upvotes: 1

Everts
Everts

Reputation: 10701

Take the UNIX timestamps when the user leaves the session and store it on the device via PlayerPrefs.

When the user comes back, grab that data from PlayerPrefs and compare it with the current timestamp.

That won't prevent user to time travel as this would require a server storage.

private void OnLeaveSession()
{
    long timestamp= (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds;
    string value = timestamp.ToString();
    PlayerPrefs.SetString("Time", value);
}

private void OnResumeSession()
{
    long timestamp= (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds;
    string value = PlayerPrefs.GetString("Time");
    long oldTimestamp = Convert.ToInt64(value);
    long elapsedSeconds = timestamp - oldTimestamp;
    OnResumeSession(elapsedSeconds); // forward to listeners
}

OnResumeSession would be an event but you can also perform actions within the method.

Upvotes: 1

Alok
Alok

Reputation: 828

Instead of using client side logics, use server side states and DB to save user timer states or you simply use login time [where timer starts] to save in DB and when user login again or resume playing, call the backend api to match offset times between the client and server times.

if user time is expired on server shows what you want to show and so on. another approach to do so is for less error chances add a server side state and user side local storage/file storage for last state of timer and can resume from there and match with server to do corrections as necessary.

the key is last time offset.

Upvotes: 1

Related Questions