- Home /
C# countdown timer
I'm trying to create a c# countdown timer for my level which should also be displayed in the GUI. The player needs to destroy certain items to get extra time. If the player runs out of time it's game over. It the player destroyed all the items they are presented with the time left and then can play again to see if they can finish the level faster with more time remaining.
I'm not sure what the script is to initiate a timer and then count down with seconds. The initial time should obviously be a public parameter you can tweak from inside the editor.
Running out of time should run an if statement to initiate a game over screen for losing. Destroying all the objects should stop the timer and record the remaining time to display in the winning game over screen.
Destroying certain objects will add time to the timer in seconds or fractions of seconds.
So I know what I want to do, but the Syntax is giving me nightmares. :-O Any help will be appreciated.
Answer by rutter · Mar 09, 2012 at 01:06 AM
You could create a script that keeps track of how much time is left.
That object's update loop can subtract Time.deltaTime
from that value, and check if it's below zero:
var timeLeft = 30;
function Update()
{
timeLeft -= Time.deltaTime;
if ( timeLeft < 0 )
{
GameOver();
}
}
Other objects could access that value, to display it in the GUI or add to it as needed.
That's definitely Javascript. The asker requested C#.
Translated to C# it would be
float timeLeft = 30.0f;
void Update()
{
timeLeft -= Time.deltaTime;
if(timeLeft < 0)
{
GameOver();
}
}
-Thanks to Stone Legion for telling me that timeLeft is meant to be a float.
int timeLeft = 30; should be a float, not int as Time.deltaTime returns a float.
Hello, I know it should work but apparently i do something wrong. Wrote your code in Update function but it is not working. When i set "float timeLeft = 30.0f;" it is always like 29,98108 and changing only 3 last digits.
$$anonymous$$ake sure you are defining timeLeft=30.0f outside of the update function !! Sounds like this is the issue.
public float blablabla = 10 ;
void Update()
{
blablabla -= Time.deltaTime;
if( blablabla < 0) {print ("Rutter cool"); }
}
Answer by U_Ku_Shu · Nov 25, 2016 at 09:57 AM
float currCountdownValue;
public IEnumerator StartCountdown(float countdownValue = 10)
{
currCountdownValue = countdownValue;
while (currCountdownValue > 0)
{
Debug.Log("Countdown: " + currCountdownValue);
yield return new WaitForSeconds(1.0f);
currCountdownValue--;
}
}
To start you need to call:
StartCoroutine(StartCountdown());
Yeah I think Coroutine is the best way for this stuff if you want to make it separate and more organised.
how would i go by and make the countDownValue public in the inspector? or even accessable with other scripts?
You would use public float currCountdownValue;
in line 1.
As noted in the reply above you'd just have to mark it as public, or if you wanted it accessible in the Inspector but didn't need to access it from other scripts you could use [SerializeField] float currCountdownValue;
.
Answer by krister.collin · Mar 09, 2012 at 07:43 AM
Michael,
That's quite a request, but I like a challenge, so here we go.
Firstly, the structure that probably best suits this is: - Game Controller (in charge of game win/loss and messaging) - Timer (GuiText object that displays the time left on screen. It is VERY important that Timer is a child of the Game Controller gameobject) - Items (the onscreen, destructable items you mentioned. These must also be child objects of the Game Controller)
The Game Controller would look something like this:
using UnityEngine;
using System.Collections;
public float timeIncrease = 2;
public bool timeElapsed = false;
public int items;
void Start()
{
//Gather how many items are remaining
GameObject[] items = GameObject.FindObjectsWithTag("items") as GameObject[];
itemsRemaining = items.length;
//The timer, as a child of this gameobject, receive this and start the countdown using the timeRemaining variable
BroadcastMessage("Start Timer", timeRemaining);
}
void Update()
{
if (itemsRemaining == 0)
{
//You win!
}
if (timeElapsed)
{
//You lose!
}
}
//If the game controller receives this signal from the timer, it will end the game
void timeHasElapsed()
{
timeElapsed = true;
}
//If the Game Controller receives this signal from a destroyed item,
// it sends a message to the time object to increase the time left
void itemDestroyed()
{
increaseTime();
}
void increaseTime()
{
broadcastMessage("timeIncrease", timeIncrease)
}
//I've included this dead function because I can't test the code myself right now and I don't want to leave
// you with errors. IT may or may not be needed, though.
void timeIncrease
{}
The purpose of the Game Controller would be to receive the happenings of both the items and timers and pass the appropriate responses back and forth, as well as handle the win/lose condition.
Then, you would have this script attached to your timer object:
using UnityEngine;
using System.Collections;
public float timeRemaining = 60f;
void Start()
{
InvokeRepeating("decreaseTimeRemaining", 1.0, 1.0)
}
void Update()
{
if (timeRemaining == 0)
{
sendMessageUpward("timeElapsed");
}
GuiText.text = timeRemaining + " Seconds remaining!";
}
void decreaseTimeRemaining()
{
timeRemaining --;
}
//may not be needed, left it in there
void timeElapsed()
{}
And, in the script for your onscreen items, you would include this:
void OnDestroy()
{
SendMessageUpwards("itemDestroyed")
}
void itemDestroyed()
{}
I have to apologise in advance, though, I have no ability to test this code right now and I had to crank it out quickly, so it will have errors, but remember, Game Controller is the parent to the timer and items, as they will have to send messages back and forth and, in this code, the game controller will handle that.
this seems pretty good if you ask me. The only thing that I personally would have done differently to control time more is use System.Diagnostics.Stopwatch.
This way you can start the timer when you want to and the time displayed in the GUI is (int)timeRemaining - Stopwatch.Elapsed.Seconds
Answer by Denscrivent · Jun 17, 2015 at 10:01 AM
I have figured out how to make a countdown timer.
public class StartCountdown : MonoBehaviour {
int time,a;
float x;
public bool count;
public string timeDisp;
void Start () {
time = 3;
count = false;
}
// Update is called once per frame
void FixedUpdate (){
if (count){
timeDisp = time.ToString ();
GameObject.Find ("StartCounter").GetComponent<Text> ().text = timeDisp;
x += Time.deltaTime;
a = (int)x;
print (a);
switch(a){
case 0: GameObject.Find ("StartCounter").GetComponent<Text> ().text = "3"; break;
case 1: GameObject.Find ("StartCounter").GetComponent<Text> ().text = "2"; break;
case 2: GameObject.Find ("StartCounter").GetComponent<Text> ().text = "1"; break;
case 3: GameObject.Find ("StartCounter").GetComponent<Text> ().enabled = false;
count = false; break;
}
}
}
}
$$anonymous$$ore easy way with a lot less redundent stuff that you have.
if (count) { GameObject.Find ("StartCounter").GetComponent ().text = ""+timeDisp; x += Time.deltaTime; a = (int)x; GameObject.Find ("StartCounter").GetComponent ().text = ""+a; if(a==0) count=false; }
Hard to follow your code if you name variables like this.
Answer by MyrDovg · Oct 30, 2017 at 11:31 AM
float totalTime = 120f; //2 minutes
private void Update()
{
totalTime -= Time.deltaTime;
UpdateLevelTimer(totalTime );
}
public void UpdateLevelTimer(float totalSeconds)
{
int minutes = Mathf.FloorToInt(totalSeconds / 60f);
int seconds = Mathf.RoundToInt(totalSeconds % 60f);
string formatedSeconds = seconds.ToString();
if (seconds == 60)
{
seconds = 0;
minutes += 1;
}
timer.text = minutes.ToString("00") + ":" + seconds.ToString("00");
}
Your answer
Follow this Question
Related Questions
Problems in c# countdown timer 1 Answer
How to stop a timer with GUI button? 1 Answer
How to add a counter on screen! 2 Answers
Countdown timer into text c# 1 Answer
How to realize accurate time counter (millisecond precision) 3 Answers