Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Countdown Timer (In days and hours)

Discussion in 'Scripting' started by Johan_Liebert123, May 20, 2021.

  1. Johan_Liebert123

    Johan_Liebert123

    Joined:
    Apr 15, 2021
    Posts:
    474
    Hello all. I'm working on a timer currently. I know how to make a normal timer but how do I make one which goes down in days and hours? What would be needed?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,020
    "Hours and days" makes me think you're wanting things to happen even when your app isn't running.

    This is known as background push notifications and is an enormous collection of very platform-specific engineering.

    If it's just a counter that only runs when the app runs, a day-long counter is just a bigger number than an hour-long counter.
     
  3. Johan_Liebert123

    Johan_Liebert123

    Joined:
    Apr 15, 2021
    Posts:
    474
    Yes, that's exactly what I'm doing, i'm making a counter which runs even if the app isn't running, it's not like a in game counter. I'm making a pass, so like every time you win or something like that you get rewards. I'm starting with a countdown for when the pass ends, which is whatever days.

    The thing is to make a countdown which lasts 30 days or whatever is confusing me, I can make a timer which lasts 2 min or 10 or whatever, but Im not sure how to make a timer run even if i'm not in play mode in the editor

    Also, what happened to the other person who sent a message here???
     
  4. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Having a timer run while your app isn't, isn't going to happen. Even if you did manage to do that, there's a myriad of reasons why the device itself would be switched off, and poof goes your timer with it. So making a timer most definitely isn't what you should be doing for managing long periods of time. At the same time, idle games exist and manage this properly.

    One way is to cache the DateTime a task started, and compare it with the current DateTime, to get the time passed. This derived difference is what you use to determine how much of a long period of time has elapsed. You still need a timer for what happens in the short term, and consolidate it with the DateTime comparison.

    A naïve implementation of this is probably prone to cheating via the player changing the time settings of their device, but security measures or more secure alternate methods are a separate discussion, even if the overall concept remains the same.
     
  5. Mostly what Laperen says:
    Except if you're on mobile. Then you can write special task, which runs when your game is in the background (or your game is in the background, you need to research how to do these things, I'm not an experienced mobile developer), so you can put a timer in the notification area.

    Or what you see above, store when you started, when the game starts, read the current datetime and calculate the difference, then run your timer as if it were running all along.
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,020
    These are called local notifications and they happen outside of Unity, with special code you must integrate to transact with the operating system, telling it when and how to wake up your app.

    And first time your app asks for one, generally the user gets notified if they want to allow your app to do that. You cannot bypass that, so since at least half the people say "no," your app has to still work on fallback timers.

    As @Laperen notes, you can just throw some DateTime data in a save file and check it when the app starts next time and process all the timers that have expired. Doing this is super-easy, as your app is fully running and you have full control to pop up UI stuff, send the player to parts of the app, etc.

    As for the time computations there are helper functions in System.DateTime to do all that stuff.

    Either way, the second half should be the first one you concentrate on because that has to be there regardless if you get so bold as to do notifications through the OS.
     
  7. Johan_Liebert123

    Johan_Liebert123

    Joined:
    Apr 15, 2021
    Posts:
    474
    Thank you everyone for your reply's, everything is basically making sense. I reckon the best way would be what basically all you 3 said. Getting the current date and time and running it from the to a set date/time. As @Kurt-Dekker said, using
    System.DateTime


    What I've just tested to see how it actually works. I used Debug.Log to see what it actually does using this
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class BrawlPassTimer : MonoBehaviour
    6. {
    7.  
    8.     void Start()
    9.     {
    10.         Debug.Log(System.DateTime.Now.ToString());
    11.     }
    12.     void Update()
    13.     {
    14.        
    15.     }
    16. }
    17.  
    And it just debug's the current time, I've also tested some other features and now started on something like this!
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5. using UnityEngine.UI;
    6.  
    7. public class BrawlPassTimer : MonoBehaviour
    8. {
    9.     [SerializeField] DateTime currentDate;
    10.     [SerializeField] DateTime startDate;
    11.     [SerializeField] DateTime endDate;
    12.     public Text FinishTime;
    13.     void Start()
    14.     {
    15.         currentDate = DateTime.Now;
    16.         //startDate = ??
    17.         TimeSpan difference = currentDate.Subtract(startDate);
    18.     }
    19.     void Update()
    20.     {
    21.        
    22.     }
    23. }
    24.  
    One question is how can I set a start date as well as a end date?
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,020
    What does this question mean? You can create any date you like with constructors from System.DateTime. It can be absolute, such as December 25, 2021, or it can be relative with the TimeSpan functions, eg "today plus 5 days."
     
  9. When you start the task, you need to store the current timestamp or datetime or whatever you choose (probably timestamp is good since it's only numbers). You can store it in a file or in PlayerPrefs (which is also a file, but Unity handles it for you). When you open up your game, you try to read it, if it exists and contains a number, then you read it, convert it to your startdate and compare it to the current date so you know where your counter is. Then when your task is over you just clear out the number.
     
  10. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    If you just need this in game, but you need it to track correctly whether the game is opened or closed, I use DateTime.Now.Ticks and then convert that into seconds (you divide it by some large number, I forget off the top of my head, but I'm sure it is easily googled). To pick a time 24 hours from now, you add 86400 seconds (that's the number of seconds in a day). You can save it with either PlayerPrefs or your own data file.
     
    Last edited: May 20, 2021
  11. Johan_Liebert123

    Johan_Liebert123

    Joined:
    Apr 15, 2021
    Posts:
    474
    Hey Kurt, I figured it out by the way on how to set a start date, thanks for the advice.
     
  12. Johan_Liebert123

    Johan_Liebert123

    Joined:
    Apr 15, 2021
    Posts:
    474
    Is it necessary to store it in PlayerPrefs, and I don't understand what am I actually storing in there, also I've got this for a starter and everything works fine
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5. using UnityEngine.UI;
    6. using TMPro;
    7.  
    8. public class BrawlPassTimer : MonoBehaviour
    9. {
    10.     [SerializeField] DateTime currentDate;
    11.     [SerializeField] DateTime startDate;
    12.     [SerializeField] DateTime endDate;
    13.     public TMP_Text FinishTimeText;
    14.     bool timer = false;
    15.     void Start()
    16.     {
    17.         // Setting timer start and end dates
    18.  
    19.         currentDate = DateTime.Now; // Checking current date, time etc
    20.         Debug.Log(currentDate); // Checking if it actually shows current date
    21.         startDate = new DateTime(2021, 5, 22, 18, 0, 0); // Set the start date
    22.         Debug.Log(startDate); // Checking if it actually sets the start date
    23.         endDate = new DateTime(2021, 5, 23, 18, 0, 0); // Set the end date
    24.         Debug.Log(endDate); // Checking if it actually sets the end date
    25.     }
    26.     void Update()
    27.     {
    28.         if(currentDate == startDate)
    29.         {
    30.             // Start the timer
    31.             timer = true;
    32.         }
    33.         if(currentDate == endDate)
    34.         {
    35.             // Stop the timer
    36.             timer = false;
    37.         }
    38.     }
    39. }
    40.  
    What's next, how do I move on from here?
     
  13. Johan_Liebert123

    Johan_Liebert123

    Joined:
    Apr 15, 2021
    Posts:
    474
    Hello Joe, Thanks for your advice, haven't really read about DateTime.Now.Ticks, I'll get into the documentation, I've also posted what I've got so far above an ideas what I could to next
     
  14. Johan_Liebert123

    Johan_Liebert123

    Joined:
    Apr 15, 2021
    Posts:
    474
    Hello all, thanks for everyone's help, I have finally come up with a solution, I'd like to thank all of you for your help. Here is the script
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5. using UnityEngine.UI;
    6. using TMPro;
    7. using System.Globalization;
    8.  
    9. public class BrawlPassTimer : MonoBehaviour
    10. {
    11.     [SerializeField] DateTime currentDate;
    12.     [SerializeField] DateTime startDate;
    13.     [SerializeField] DateTime endDate;
    14.     public TMP_Text FinishTimeText;
    15.     void Start()
    16.     {
    17.         // Setting timer start and end dates
    18.  
    19.         currentDate = DateTime.Now; // Checking current date, time etc
    20.         Debug.Log(currentDate); // Checking if it actually shows current date
    21.         startDate = new DateTime(2021, 5, 22, 18, 0, 0); // Set the start date
    22.         Debug.Log(startDate); // Checking if it actually sets the start date
    23.         endDate = new DateTime(2021, 5, 23, 18, 0, 0); // Set the end date
    24.         Debug.Log(endDate); // Checking if it actually sets the end date
    25.         TimeSpan timeDifference = startDate - currentDate; // Seeing what is the time difference
    26.         string time = new DateTime(timeDifference.Ticks).ToString("dd:hh:mm:ss");
    27.         Debug.Log(time);
    28.         FinishTimeText.text = time;
    29.     }
    30. }
    31.  
    But still some I need help, I can't use
    Code (CSharp):
    1. if (!startDate == currentDate)
    2.         {
    3.  
    4.         }
    The operator
    !
    for DateTime, so I can't figure out the time until the event starts or whatever, what can I do instead?
     
  15. Johan_Liebert123

    Johan_Liebert123

    Joined:
    Apr 15, 2021
    Posts:
    474
    Hello all, thanks for everyone's help, I have finally come up with a solution, I'd like to thank all of you for your help. Here is the script
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5. using UnityEngine.UI;
    6. using TMPro;
    7. using System.Globalization;
    8.  
    9. public class BrawlPassTimer : MonoBehaviour
    10. {
    11.     [SerializeField] DateTime currentDate;
    12.     [SerializeField] DateTime startDate;
    13.     [SerializeField] DateTime endDate;
    14.     public TMP_Text FinishTimeText;
    15.     void Start()
    16.     {
    17.         // Setting timer start and end dates
    18.  
    19.         currentDate = DateTime.Now; // Checking current date, time etc
    20.         Debug.Log(currentDate); // Checking if it actually shows current date
    21.         startDate = new DateTime(2021, 5, 22, 18, 0, 0); // Set the start date
    22.         Debug.Log(startDate); // Checking if it actually sets the start date
    23.         endDate = new DateTime(2021, 5, 23, 18, 0, 0); // Set the end date
    24.         Debug.Log(endDate); // Checking if it actually sets the end date
    25.         TimeSpan timeDifference = startDate - currentDate; // Seeing what is the time difference
    26.         string time = new DateTime(timeDifference.Ticks).ToString("dd:hh:mm:ss");
    27.         Debug.Log(time);
    28.         FinishTimeText.text = time;
    29.     }
    30. }
    31.  
    But still some I need help, I can't use
    Code (CSharp):
    1. if (!startDate == currentDate)
    2.         {
    3.  
    4.         }
    The operator
    !
    for DateTime, so I can't figure out the time until the event starts or whatever, what can I do instead?
     
  16. rushilkachhadiya

    rushilkachhadiya

    Joined:
    Jul 21, 2022
    Posts:
    1
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using TMPro;
    5. using UnityEngine;
    6. using UnityEngine.UI;
    7.  
    8. public class NewBehaviourScript : MonoBehaviour
    9. {
    10.     [SerializeField] DateTime currentDate;
    11.     [SerializeField] DateTime startDate;
    12.     [SerializeField] DateTime endDate;
    13.     //public TMP_Text FinishTimeText;
    14.     public bool timer;
    15.     void Start()
    16.     {
    17.         // Setting timer start and end dates
    18.         startDate = new DateTime(2022, 7, 21, 10, 52, 0); // Set the start date
    19.         endDate = new DateTime(2022, 7, 28, 10, 52, 0); // Set the end date
    20.     }
    21.     void Update()
    22.     {
    23.         currentDate = DateTime.Now;
    24.         if(currentDate > startDate && currentDate < endDate)
    25.         {
    26.             // Start the timer
    27.             timer = true;
    28.         }
    29.         else
    30.         {
    31.             // Stop the timer
    32.             timer = false;
    33.         }
    34.     }
    35. }
    36.