Search Unity

Question Timer should also run if the application is closed

Discussion in 'Scripting' started by Knello, Sep 16, 2020.

  1. Knello

    Knello

    Joined:
    Jul 27, 2020
    Posts:
    50
    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:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using TMPro;
    6. using System;
    7.  
    8. public class DailyCoins : MonoBehaviour
    9. {
    10.     public Button dailyCoins;
    11.    
    12.     public float startingTime;
    13.     [SerializeField] TextMeshProUGUI timerText1;
    14.     int collectedCoins;
    15.     float timer1 = 0f;
    16.  
    17.     void Update()
    18.     {
    19.         FormatText1();
    20.        
    21.     }
    22.  
    23.    void Start()
    24.     {
    25.         PlayerPrefs.GetString("CollectedCoins", DateTime.Now.ToString());
    26.     }
    27.    
    28.  
    29.     public void StartTimer()
    30.     {
    31.         StartCoroutine(TimeoutEndTurnButton());
    32.     }
    33.     IEnumerator TimeoutEndTurnButton()
    34.     {
    35.         dailyCoins.interactable = false;
    36.         GameDataManager.AddCoins(500);
    37.         GameSharedUI.Instance.UpdateCoinsUIText();
    38.         StartCoroutine(Timer());
    39.         yield return new WaitForSeconds(60f);
    40.         PlayerPrefs.SetString("CollectedCoins", DateTime.Now.ToString());
    41.         dailyCoins.interactable = true;
    42.        
    43.     }
    44.    
    45.     public IEnumerator Timer()
    46.     {
    47.         timer1 = startingTime;
    48.  
    49.         do
    50.         {
    51.             timer1 -= Time.deltaTime;
    52.  
    53.             FormatText1();
    54.  
    55.             yield return null;
    56.         }
    57.         while (timer1 > 0);
    58.     }
    59.  
    60.     public void FormatText1()
    61.     {
    62.         int days = (int)(timer1 / 86400) % 365;
    63.         int hours = (int)(timer1 / 3600) % 24;
    64.         int minutes = (int)(timer1 / 60) % 60;
    65.         int seconds = (int)(timer1 % 60);
    66.  
    67.         timerText1.text = "";
    68.         if (days > 0) { timerText1.text += days + "d"; }
    69.         if (hours > 0) { timerText1.text += hours + "h"; }
    70.         if (minutes > 0) { timerText1.text += minutes + "m"; }
    71.         if (seconds > 0) { timerText1.text += seconds + "s"; }
    72.     }
    73.  
    74.    
    75. }
    76.  
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    You're not doing anything with the result of this:
    Code (CSharp):
    1. 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.
     
    Joe-Censored likes this.
  3. Knello

    Knello

    Joined:
    Jul 27, 2020
    Posts:
    50
    I just tried somethin with the playerprefs but i does not work. So how can i get it to work?
     
  4. Knello

    Knello

    Joined:
    Jul 27, 2020
    Posts:
    50
    Anyone who can help me?
     
  5. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    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.
     
  6. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    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.
     
    PraetorBlue likes this.
  7. Knello

    Knello

    Joined:
    Jul 27, 2020
    Posts:
    50
    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.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using System;
    5.  
    6.  
    7. public class Chest : MonoBehaviour
    8. {
    9.     public Button chestButton;
    10.     private ulong lastChestOpen;
    11.  
    12.     private void Start()
    13.     {
    14.        
    15.         lastChestOpen = ulong.Parse(PlayerPrefs.GetString("LastChestOpen" ));
    16.     }
    17.  
    18.     private void Update()
    19.     {
    20.         if(!chestButton.IsInteractable())
    21.         {
    22.             ulong diff = ((ulong)DateTime.Now.Ticks - lastChestOpen);
    23.             ulong m = diff / TimeSpan.TicksPerMillisecond;
    24.  
    25.             float secondsLeft = (float)(3000.0f - m) / 1000.0f;
    26.  
    27.             if (secondsLeft < 0)
    28.             {
    29.                 chestButton.interactable = true;
    30.                 return;
    31.             }
    32.         }
    33.     }
    34.  
    35.  
    36.     public void ChestClick()
    37.     {
    38.         lastChestOpen = (ulong)DateTime.Now.Ticks;
    39.         PlayerPrefs.SetString("LastChestOpen", lastChestOpen.ToString());
    40.         chestButton.interactable = false;
    41.     }
    42. }
    43.  
     
  8. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    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.
     
  9. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    Possibly your PlayerPrefs "LastChestOpen" holds an old wrong value, so simply write a new correct one (here one time if you start the game):
    Code (CSharp):
    1.  
    2.  private void Start()
    3.    {  
    4.      lastChestOpen = (ulong)DateTime.Now.Ticks;
    5.      PlayerPrefs.SetString("LastChestOpen", lastChestOpen.ToString());
    6.      lastChestOpen = ulong.Parse(PlayerPrefs.GetString("LastChestOpen" ));
    7. }
    8.  
    Because your code is working correct as is.