- Home /
Timer counting UP instead of DOWN
I have a fairly simple script that determines how much time (in minutes and seconds) has lapsed since a certain time in the past. A custom action (e.g., add a life) is to be invoked every 30 minutes and this script is to show how much time is left until the next custom action is to happen.
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections;
public class LifeTimerScript : MonoBehaviour {
private Text timeText;
private float timeLeft;
private float timeWaited;
private float timeToWait;
private int livesToAdd;
void Awake() {
timeText = GetComponent<Text>();
}
void Start() {
// how much time has lapsed since the last action triggered?
// 'lifeTimerResetTime' holds a time in the past
TimeSpan timeDiff = DateTime.Now - GameManager.manager.lifeTimerResetTime;
timeWaited = (float) timeDiff.TotalSeconds;
// Method 'lifeTimerInSeconds()' returns a static value - 1800.0f in this case
timeToWait = GameManager.manager.lifeTimerInSeconds();
// determine how many lives need to be added
livesToAdd = (int) (timeWaited / timeToWait);
// get the remainder time to determine how long before the next life
timeLeft = timePassed % timeToWait;
if (livesToAdd > 0) {
// TODO: add lives to player
}
}
void Update() {
// count down the time
timeLeft -= Time.deltaTime;
var minutes = Mathf.FloorToInt(timeLeft / 60.0f);
var seconds = Mathf.FloorToInt(timeLeft - minutes * 60);
// display the timer to UI text
timeText.text = string.Format("{0:0}:{1:00}", minutes, seconds);
}
}
The only problem I have is that the timer ticks upward instead of downward. Everything else seems to be working. What am I missing here?
Answer by PatriceVignola · Aug 03, 2015 at 06:22 PM
The timer is working fine on my end, unless timeLeft
starts being negative, in which case the FloorToInt
method doesn't act like you want it to.
First of all, the FloorToInt
method does nothing for you here, and it's even causing a bug when timeLeft becomes negative. A simple integer division would work perfectly fine here,
For example, let's say timeLeft is -2.5 seconds. The Mathf.FloorToInt(timeLeft / 60.0f)
is going to give -1 instead of 0, whereas simply doing timeLeft / 60f
is going to give you 0 (the right value).
If you don't want to have a negative timer, simply do the following check before you decrease its value. The following will work just fine, but I am assuming you also want to do something as soon as the timer is smaller than 0 (like give more lives).
if (timeLeft < 0) {
timeLeft = timeToWait;
// Add lives here or do other stuff
}
If you want to simply leave the timer at 0 instead, just assign 0 to it instead:
if (timeLeft < 0) {
timeLeft = 0;
// Do stuff
}
I don't know exactly what you want to do, but for the problem of the timer counting up instead of down, the problem probably lies in the Mathf.FloorToInt. A simple integer division does exactly what you want to do:
int minutes = (int)(timeLeft / 60);
int seconds = (int)timeLeft - minutes * 60;
Let me know if it still doesn't work.
@Patrice - Actually, the value stored in 'timeLeft' is positive; I verified by printing the output inside the Update function, so that possibility is out. What's odd is, when I print the value of 'timeDiff' which supposedly gets executed only once inside the Start function is printing incremental values on each tick - and I'm thinking that might be what's causing the timer uptick (but WHY?)
@CrucibleLab - Are you sure the code you have right now is exactly the code snippet you posted? As I see it, it's impossible to print the timeDiff value on each tick since its scope is restricted to the Start method (so it's not changing after it has been assigned). The only way it's incrementing on each tick is if you are doing timeDiff = DateTime.Now - lastActionTime
in the Update method.
@Patrice - I updated my initial post with my code in its entirety. As you can see, timeDiff is calculated only once in the Start function. Another weirdness I noticed is, I get the same result (timer counting up) even if I change the 'timeLeft -= Time.deltaTime;' line to 'timeLeft += Time.deltaTime;'. Something must be seriously messed up.
@CrucibleLab - The problem must be elsewhere then because everything is working fine with the script you provided, as long as timeLeft is positive.
For testing purposes, if you write timeLeft = 100;
at the very end of the Start method and then write Debug.Log(timeLeft);
in your Update method, is it still counting up?
And you can't do
private float lastActionTime;
...
TimeSpan timeDiff = DateTime.Now - lastActionTime;
so there's truly something fishy with the code you posted.