Reputation: 303
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
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
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
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