Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Creating an Analog Countdown Timer

Discussion in 'Scripting' started by ATLAS-INTERACTIVE, Jul 14, 2016.

  1. ATLAS-INTERACTIVE

    ATLAS-INTERACTIVE

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    I am trying to build an analog countdown timer (wouldn't be an issue if I were working with digital), and I have tried to modify a working analog clock which uses the system time (DateTime.Now) to create a clock to do this, but I have been unsuccessful.

    I am looking for a way to use a similar approach the script below uses, in order to set a countdown (minutes and seconds in different int variables) which visually ticks down until it reaches all zero's.

    I also need to be able to trigger the countdown, but I can worry about that later.

    Here is the existing system clock code.

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3.  
    4. public class ClockAnimator : MonoBehaviour {
    5.  
    6.     private const float
    7.     hoursToDegrees = 360f / 12f,
    8.     minutesToDegrees = 360f / 60f,
    9.     secondsToDegrees = 360f / 60f;
    10.  
    11.     public Transform hours, minutes, seconds;
    12.     public bool analog;
    13.  
    14.     private void Update () {
    15.         if (analog) {
    16.             TimeSpan timespan = DateTime.Now.TimeOfDay;
    17.             hours.localRotation = Quaternion.Euler(
    18.                 0f, 0f, (float)timespan.TotalHours * -hoursToDegrees);
    19.             minutes.localRotation = Quaternion.Euler(
    20.                 0f, 0f, (float)timespan.TotalMinutes * -minutesToDegrees);
    21.             seconds.localRotation = Quaternion.Euler(
    22.                 0f, 0f, (float)timespan.TotalSeconds * -secondsToDegrees);
    23.         }
    24.         else {
    25.             DateTime time = DateTime.Now;
    26.             hours.localRotation =
    27.                 Quaternion.Euler(0f, 0f, time.Hour * -hoursToDegrees);
    28.             minutes.localRotation =
    29.                 Quaternion.Euler(0f, 0f, time.Minute * -minutesToDegrees);
    30.             seconds.localRotation =
    31.                 Quaternion.Euler(0f, 0f, time.Second * -secondsToDegrees);
    32.         }
    33.     }
    34. }
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,840
    Looks about right to me. But instead of getting a TimeSpan or DateTime, simply have a 'float' property that is the number of seconds left.

    If you want only a second hand (like every analog timer I've ever seen), then just delete the bits above that refer to hours and minutes, and you're done.

    But if you want a minutes hand too, then just calculate minutes = secsLeft / 60 and seconds = secsLeft % 60, and use those to set your minute and second hand.

    Try that, and if it's still not working, post what you have and we'll point out whatever is still incorrect.
     
  3. ATLAS-INTERACTIVE

    ATLAS-INTERACTIVE

    Joined:
    Mar 3, 2014
    Posts:
    1,421
    Not the most elegant solution in the world (or the most optimised), but I seem to have found a working solution for now.

    I have still to work out how to reset it if I need to, but for now it seems to work well.

    If you would know how to optimise something like this, please let me know.

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections.Generic;
    4.  
    5. public class CountdownClock : MonoBehaviour {
    6.  
    7.     private const float
    8.     minutesToDegrees = 360f / 60f,
    9.     secondsToDegrees = 360f / 60f;
    10.  
    11.     public int countdownMinutes, countdownSeconds;
    12.     public int internalSeconds;
    13.     private DateTime zero;
    14.     private bool finished;
    15.  
    16.     public Transform minutes, seconds;
    17.     public bool analog;
    18.  
    19.     private TimeSpan remainingTime;
    20.  
    21.     private void Start()
    22.     {
    23.         SetTime();
    24.     }
    25.  
    26.     private void Update ()
    27.     {
    28.         if(DateTime.Now >= zero)
    29.         {
    30.             finished = true;
    31.         }
    32.         else
    33.         {
    34.             finished = false;
    35.         }
    36.  
    37.         if (analog) {
    38.             if (!finished)
    39.             {
    40.                 remainingTime = DateTime.Now - zero;
    41.                 minutes.localRotation = Quaternion.Euler(
    42.                     0f, 0f, (float)remainingTime.Minutes * -minutesToDegrees);
    43.                 seconds.localRotation = Quaternion.Euler(
    44.                     0f, 0f, (float)remainingTime.TotalSeconds * -secondsToDegrees);
    45.             }
    46.         }
    47.         else {
    48.             if (!finished)
    49.             {
    50.                 remainingTime = DateTime.Now - zero;
    51.                 minutes.localRotation =
    52.                     Quaternion.Euler(0f, 0f, remainingTime.Minutes * -minutesToDegrees);
    53.                 seconds.localRotation =
    54.                     Quaternion.Euler(0f, 0f, remainingTime.Seconds * -secondsToDegrees);
    55.             }
    56.         }
    57.     }
    58.  
    59.     void SetTime()
    60.     {
    61.         zero = DateTime.Now;
    62.         zero = zero.AddMinutes(countdownMinutes);
    63.         zero = zero.AddSeconds(countdownSeconds);
    64.     }
    65. }
     
    JoeStrout likes this.