0

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.

Kathryn Hazuka
  • 216
  • 1
  • 7
Dennis Liu
  • 303
  • 5
  • 21
  • 2
    Instead of continuing a timer, save the state when you exit the game. Then when the game starts again calculate the offset between the saved state and the current time and continue the timer from there. – Cheesebaron Jul 15 '16 at 10:48
  • 1
    ^ Well That is one good solution. But I guess if the purpose is to send push notifications after certain time then one might require to create a background service using native android code or some 3rd party plugins. – Umair M Jul 15 '16 at 11:50
  • For goodness sake ... just use Invoke. – Fattie Jul 15 '16 at 16:03

3 Answers3

1

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.

Alok
  • 808
  • 13
  • 40
1

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.

Everts
  • 10,408
  • 2
  • 34
  • 45
  • That's Great, But at my code above how to convert elapsedseconds to Hour, Minute, and seconds ? – Dennis Liu Jul 15 '16 at 13:14
  • @DennisLiu check my answer for this – Umair M Jul 15 '16 at 13:41
  • You don't want to convert to hours minutes or seconds, it makes it all more complex. Consider you want to check if 2h have passed and 1h37m23s have passed, how do you check the two hours? With elapsedSeconds, just check if > 7200. – Everts Jul 15 '16 at 16:32
1

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
Umair M
  • 10,298
  • 6
  • 42
  • 74
  • Thats Great @Umair M, I am sorry i can;t tick two answer. But thanks for your help.. :) – Dennis Liu Jul 15 '16 at 14:09
  • Use DateTime instead, http://stackoverflow.com/questions/249760/how-to-convert-a-unix-timestamp-to-datetime-and-vice-versa – Everts Jul 15 '16 at 16:33