Racing Timer (again)

Hi everyone,

I know this is not the first thread dedicated to creating a realistic racing timer, but after scouring over the forums, I haven’t found anything satisfactory. I found this snippet in another thread:

var startTime = 0;

function Update () {
//The time taken so far
timeTaken = startTime + Time.time;
// Format the time nicely
guiText.text = FormatTime (timeTaken);

}


//Format time like this
// 17[minutes]:21[seconds]:05[fraction]

function FormatTime (time)

{

     var intTime : int = time;
     var minutes : int = intTime / 60;
     var seconds : int = intTime % 60;
     var fraction : int = time * 10;
     fraction = fraction % 10;
     
     //Build string with format
     // 17[minutes]:21[seconds]:05[fraction]
     
   //  timeText = minutes.ToString () ;
     //timeText = timeText + seconds.ToString ();
	  timeText = String.Format ("{0:00}:{1:00}:{2:00}", minutes, seconds,fraction);

    // timeText +=  fraction.ToString ();
     return timeText;
}

however the miliseconds and seconds don’t align properly. The seconds are ticking over when miliseconds are at approximately 4 (not 0).

Also, I want the game to have a timer that follows the following format for minutes:seconds:miliseconds

00:00:000

where the miliseconds (furthest right) are three digits long. So far I am having to luck really understanding how String.Format works.

Can anyone help?

  • C

I don’t have the documentation in front of me right now, but I think you can get an extra place in the ‘milliseconds’ field by adding an extra zero, i.e.:

String.Format ("{0:00}:{1:00}:{2:000}", minutes, seconds,fraction);

Regarding time keeping, I wouldn’t use Time.time for this. Time.time is a float, so unless there’s some aspect of Time.time I’m not aware of, the precision of ‘time’ will decrease the longer the game runs. This may not be noticeable in most cases, but with a precision timer such as in your example, I imagine you might see some problems eventually.

What you might consider instead is storing the time using three integers (minutes, seconds, milliseconds), converting Time.deltaTime to milliseconds, and then updating the time ‘manually’ based on that. Presumably, this would give you consistent results no matter how long the game runs.

As for ticking over at 4 rather than 0, keep in mind that unless you’re running at 1000 frames per second, you’re not going to see every individual millisecond on screen. Under normal circumstances, it’s perfectly expected that the first millisecond you’d see after the seconds ticked over would be a value other than 0. (If however you’re seeing the milliseconds cross over the zero mark and then the seconds tick over after that, that might be a precision problem, in which case handling the time variables as integers as described earlier should solve the problem.)

adding an extra 0 to the 2:000 adds a zero, but the miliseconds number is still singular, and sits at the rightmost slot. What I want is for miliseconds to be a 3 digit number, with the rightmost two numbers literally blazing by. The actual miliseconds should be the leftmost of the three 0’s.

I’ll give the time handling idea you came up with a try as well. Thanks!

Try searching for ‘string format padding’. (I can’t remember the syntax off the top of my head, but maybe someone else will post an example.)

[Edit: Can’t test it now, but try {2:smile:3}. Or maybe {2,-3}. And there’s also string.PadLeft() and PadRight().]

no, 2:smile:3 made no change and 2,-3 removed the extra zeros.

Thank you for trying though :slight_smile:

Hm, I’ve got a similar clock in one of my projects; I used {0:smile:2} (only needed two digits), and it worked fine (and I’m not sure why three digits would be any different).

Are you sure you got the syntax right? Maybe you could post your revised code.

Try this:

function FormatTime (time)

{

     var intTime : int = time;
     var minutes : int = intTime / 60;
     var seconds : int = intTime % 60;
     var fraction : int = time * 1000;
     fraction = fraction % 1000;
     timeText = String.Format ("{0:00}:{1:00}:{2:000}", minutes, seconds,fraction);
     return timeText;
}

Gil Beyruth

That seems to have fixed it. Thank you firstpixel!

As for my precision problem, Using three integers based on Time.deltaTime sounds dandy. How can I go about converting Time.deltaTime into milliseconds?

I apologize, I’m still really new to coding :slight_smile:

Are you saying that fixed the padding problem? If so, didn’t I suggest that same syntax earlier? :S

Time.deltaTime is a float representing a value in seconds. There are 1000 milliseconds in a second, so first you have to multiply by 1000. Then, you cast the result to an int (you can round if you want, although truncating will probably suffice).

In C# (for example), it might look something like this:

int ms = (int)(Time.deltaTime * 1000f);

That will give you the elapsed milliseconds for the current update cycle. You’ll then need to add that to your running total, and update the rest of the time variables (seconds, minutes) accordingly when the milliseconds counter rolls over.

Thank you so much for your help Jesse!

It turned out that my intTime : int = time was rounding time as it had to typecast it as an int. I added a Mathf.Floor to it to make it

var intTime : int = Mathf.Floor(time);

and now it works like a charm.

Thanks!