Timer should also run if the application is closed

Hello, i got a problem with my script. As you can see I want that the timer runs also if the game is closed. I.e I press a button and the timer show 2 min left and I close the game, wait 5 seconds and restart ist the timer should show 1 min and 55 secs. So how can do it I tried it like this but it does not work so maybe you can help me:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System;

public class DailyCoins : MonoBehaviour
{
    public Button dailyCoins;

    public float startingTime;
    [SerializeField] TextMeshProUGUI timerText1;
    int collectedCoins;
    float timer1 = 0f;

    void Update()
    {
        FormatText1();

    }

   void Start()
    {
        PlayerPrefs.GetString("CollectedCoins", DateTime.Now.ToString());
    }


    public void StartTimer()
    {
        StartCoroutine(TimeoutEndTurnButton());
    }
    IEnumerator TimeoutEndTurnButton()
    {
        dailyCoins.interactable = false;
        GameDataManager.AddCoins(500);
        GameSharedUI.Instance.UpdateCoinsUIText();
        StartCoroutine(Timer());
        yield return new WaitForSeconds(60f);
        PlayerPrefs.SetString("CollectedCoins", DateTime.Now.ToString());
        dailyCoins.interactable = true;

    }

    public IEnumerator Timer()
    {
        timer1 = startingTime;

        do
        {
            timer1 -= Time.deltaTime;

            FormatText1();

            yield return null;
        }
        while (timer1 > 0);
    }

    public void FormatText1()
    {
        int days = (int)(timer1 / 86400) % 365;
        int hours = (int)(timer1 / 3600) % 24;
        int minutes = (int)(timer1 / 60) % 60;
        int seconds = (int)(timer1 % 60);

        timerText1.text = "";
        if (days > 0) { timerText1.text += days + "d"; }
        if (hours > 0) { timerText1.text += hours + "h"; }
        if (minutes > 0) { timerText1.text += minutes + "m"; }
        if (seconds > 0) { timerText1.text += seconds + "s"; }
    }


}

You're not doing anything with the result of this:

PlayerPrefs.GetString("CollectedCoins", DateTime.Now.ToString());

I guess you'd want to compare the current time with the time you saved and see how much time has passed around that line of code.

1 Like

I just tried somethin with the playerprefs but i does not work. So how can i get it to work?

Anyone who can help me?

You aren't being very clear about what doesn't work. You're trying to get us to help you solve a problem without any context. If you plan to do this, the basic principle is the same no matter what you do. You have to record a time stamp somewhere and then retrieve it and calculate how much time has passed.

For this sort of thing I use DateTime.Now.Ticks, as being a single number it is easier to work with than string based timestamps.

As for what "didn't work" you'll either have to be extremely specific or you're on your own basically. My Mind Reader 3000 is currently on RMA.

1 Like

Yeah I tried it with DateTime.Now.Ticks too but I get an error may you know how to fix it. So the console says that the Input String was not in a correct form.

using UnityEngine;
using UnityEngine.UI;
using System;


public class Chest : MonoBehaviour
{
    public Button chestButton;
    private ulong lastChestOpen;

    private void Start()
    {

        lastChestOpen = ulong.Parse(PlayerPrefs.GetString("LastChestOpen" ));
    }

    private void Update()
    {
        if(!chestButton.IsInteractable())
        {
            ulong diff = ((ulong)DateTime.Now.Ticks - lastChestOpen);
            ulong m = diff / TimeSpan.TicksPerMillisecond;

            float secondsLeft = (float)(3000.0f - m) / 1000.0f;

            if (secondsLeft < 0)
            {
                chestButton.interactable = true;
                return;
            }
        }
    }


    public void ChestClick()
    {
        lastChestOpen = (ulong)DateTime.Now.Ticks;
        PlayerPrefs.SetString("LastChestOpen", lastChestOpen.ToString());
        chestButton.interactable = false;
    }
}

Somewhere you are trying to convert a string into something and it can't do the conversion. Possibly your ulong.Parse call. I would debug.log the value of your playerprefs or get one of the free playerpref viewers to add onto your unity editor to see what your values are.

Possibly your PlayerPrefs "LastChestOpen" holds an old wrong value, so simply write a new correct one (here one time if you start the game):

 private void Start()
   {   
     lastChestOpen = (ulong)DateTime.Now.Ticks;
     PlayerPrefs.SetString("LastChestOpen", lastChestOpen.ToString());
     lastChestOpen = ulong.Parse(PlayerPrefs.GetString("LastChestOpen" ));
}

Because your code is working correct as is.