Below is an example of a countdown timer I’m reasonably in love with. Thanks to the other forum contributors for getting me started with the initial countdown code! Attach it to a parent/level Game Object for best results. Use the getters/setters to access the internal properties and start/stop the timer. Methods are kept out of the way of other scripts to prevent unintended bugs. Best of all, it lets you call a predefined method when the timer is up to handle what to do then (beep, end the level, turn red, etc.).
To invoke in another script, which is what you oughta be doing, do the following. Note that this example assumes that the calling script and countdown timer are components of the same Game Object.
var o_countdownTimer : countdownTimer;
var f_timerdone = timerDone;
o_countdownTimer = GetComponent(countdownTimer);
o_countdownTimer.setStartTime(90.0);
o_countdownTimer.setTimerDoneAction(f_timerdone);
o_countdownTimer.setTimerState(true);
function timerDone() {
guiText.text = "done!";
}
//countdownTimer: methods to handle a countdown timer
//it is always assumed that there is a guiText item available for the display output
//PRIVATE MEMBERS
private var b_timer_active : boolean; //switch to start/stop timer
private var f_timer_done; //method to be called when timer runs down
private var fl_start_time : float; //start time (in seconds)
private var fl_time_left : float; //time left (in seconds)
//PUBLIC METHODS
function getFlRemainingTime() { //get the time remaining on the clock
return fl_time_left;
}
function setTimerDoneAction(f_method_fp) { //set the method to be called when the timer is done
f_timer_done = f_method_fp;
}
function setTimerState(b_active_fp : boolean) { //set the active state of the timer
b_timer_active = b_active_fp;
}
function setStartTime(fl_time_fp : float) { //set the starting value for the countdown
fl_start_time = fl_time_fp;
}
function Update() {
if (b_timer_active) { //check to see if the timer is "on"
if (!guiText) { //check for an available GUIText component
Debug.Log("countdownTimer needs a GUIText component!");
enabled = false;
return;
} else {
doCountdown(); //decrement the time and send value to GUIText for output
}
}
}
//PRIVATE METHODS
private function doCountdown() { //
if (fl_start_time) { //make sure that we had a starting time value before conting down
fl_time_left = fl_start_time - Time.time;
fl_time_left = Mathf.Max(0, fl_time_left); //don't let the time fall below 0.0
guiText.text = outReadableTime(fl_time_left); //display the time to the GUI
if (fl_time_left == 0.0) { //if time has run out, deactivate the timer and call the followup method
b_timer_active = false;
if (f_timer_done) { //only call the followup method if we had one
f_timer_done();
}
}
} else {
Debug.Log("countdownTimer needs a value set for fl_time_left");
}
}
private function outReadableTime(fl_time_fp : float) { //format the floating point seconds to M:S
var i_minutes : int;
var i_seconds : int;
var i_time : int;
var s_timetext : String;
i_time = fl_time_fp;
i_minutes = i_time / 60;
i_seconds = i_time % 60;
s_timetext = i_minutes.ToString() + ":";
s_timetext = s_timetext + i_seconds.ToString();
return s_timetext;
}
Thanks for the contribution, phuzzy - saved me some dev time and will certainly help many others.
Just a note, at first I couldn’t get it to work because I had arbetrarily named the larger script “timer.js”. Then, based on error messages, I realized the larger script should be named countdownTimer.js, because it is called by the smaller script. I don’t think the name of the smaller script is important.
The way I set it up in my game is that I created a new empty game object, then created a GUI Text under that, and dropped both scripts onto the GUI Text.
thank you for that countdown script!
I made a small adjustment to your script to take the timeSinceLevelLoad, so the Timer always gets reset when a new scene is loaded. (It was driving me crazy, didn’t understand that it takes the time from when the application started: http://forum.unity3d.com/viewtopic.php?p=229240 )
I also added a function for adding seconds to the timer (e.g. PowerUps) and integrated the code by Nathaniel.
Here is my version:
/*
* countdownTimer: methods to handle a countdown timer
* it is always assumed that there is a guiText item available for the display output
*
*/
/*
* Private member variables
*/
private var b_timer_active : boolean; //switch to start/stop timer
private var f_timer_done; //method to be called when timer runs down
private var fl_start_time : float; //start time (in seconds)
private var fl_time_left : float; //time left (in seconds)
private var fl_time_extra : float;
/*
* Public methods
*/
function getFlRemainingTime() { //get the time remaining on the clock
return fl_time_left;
}
function setTimerDoneAction(f_method_fp) { //set the method to be called when the timer is done
f_timer_done = f_method_fp;
}
function setTimerState(b_active_fp : boolean) { //set the active state of the timer
b_timer_active = b_active_fp;
}
function setStartTime(fl_time_fp : float) { //set the starting value for the countdown
fl_start_time = fl_time_fp;
}
/*
* Update
*/
function Update() {
if (b_timer_active) { //check to see if the timer is "on"
if (!guiText) { //check for an available GUIText component
Debug.Log("countdownTimer needs a GUIText component!");
enabled = false;
return;
} else {
doCountdown(); //decrement the time and send value to GUIText for output
}
}
}
/*
* Adding seconds to the countdown, for "powerUps"
*/
function addSeconds( seconds : float ){
//Debug.Log("Adding " + seconds + " seconds!");
fl_time_extra += seconds;
}
/*
* Private methods
*/
private function doCountdown() { //
if (fl_start_time b_timer_active) { //make sure that we had a starting time value before conting down
fl_time_left = (fl_start_time - Time.timeSinceLevelLoad) + fl_time_extra;
fl_time_left = Mathf.Max(0, fl_time_left); //don't let the time fall below 0.0
guiText.text = outReadableTime(fl_time_left); //display the time to the GUI
if (fl_time_left == 0.0) { //if time has run out, deactivate the timer and call the followup method
b_timer_active = false;
if (f_timer_done) { //only call the followup method if we had one
f_timer_done();
}
}
} else {
Debug.Log("countdownTimer needs a value set for fl_time_left");
}
}
private function outReadableTime(fl_time_fp : float) { //format the floating point seconds to M:S
var i_minutes : int;
var i_seconds : int;
var i_time : int;
var s_timetext : String;
i_time = fl_time_fp;
i_minutes = i_time / 60;
i_seconds = i_time % 60;
s_timetext = i_minutes.ToString() + ":";
if (i_seconds > 9){
s_timetext = s_timetext + i_seconds.ToString();
}
else {
s_timetext = s_timetext + "0" + i_seconds.ToString();
}
return s_timetext;
}
It does seem that since this does string concatenation with the plus operator, it will probably run memory allocations. Not much, but it’s something to be aware of. I guess you could either go with mono StringBuilder or you could minimize heap growth by checking to see if the time display has changed before recreating the string - that would reduce the number of allocations from every frame to however many allocs occur in a doCountdown() call per second.
Im creating a game where you control a ball which rolls down a terrain to collect good and bad objects which effect the amount of time you have to complete the terrain. I have used your code so I have a working countdown timer but was wondering if you could help me with a few problems?
The camera is at the side of the ball not above and swings side to side a bit
How do you make the time-bonus part work? I have objects tagged as ‘correct’ and ‘wrong’ but havent got them to effect the timer. Any help??
@melbabez7: Sorry, I stopped watching this thread.
Camera: This is most likely related to the axis rotation of your ball object, make sure it’s not rotated, set all rotations to 0 and try to figure it out then. I also had that problem once.
Time bonus: Call the addSeconds() function on the timer object. You need to have it present in the object you are trying to call the function from. If you don’t know how, check out the basic scripting information in the documentation.
I’m having trouble adding these scripts, what should the file name of the 2 scripts be, what component should they be added to, and what component needs to go on the o_countdownTimer getter?
How would I alter this script to make it so the timer counts down from a specified amount of seconds and once it hits zero seconds a new scene is loaded and if there is any input the timer resets itself and begins the countdown again.
I am trying to make it when a player in the game remains idle after a number of minutes that the game restarts itself.
Any way I could utilise this to create a level start countdown. So when the level loads a 3-2-1 counts down then the controls become active. I am already using an instance of this to keep a rundown timer on my game once the player starts…
I’m guessing that it will need to be in a function Start to call it then a check in Update ?