+8 votes

How display elapsed time in game (Minute:Seconds) ?

in Engine by (201 points)

2 Answers

+9 votes
Best answer
var time_start = 0
var time_now = 0

func _ready():
    time_start = OS.get_unix_time()
    set_process(true)

func _process(delta):
    time_now = OS.get_unix_time()
    var elapsed = time_now - time_start
    var minutes = elapsed / 60
    var seconds = elapsed % 60
    var str_elapsed = "%02d : %02d" % [minutes, seconds]
    print("elapsed : ", str_elapsed)
by (9,664 points)
selected by

THX for code, but how to modify it to work well when the game is paused. Get time on start scene causes the time is calculate again after restore game from the background.

When use pause in game this code works better:

func _on_Time_Elapsed_timeout():
sec_elapsed += 1
var seconds = sec_elapsed % 60
var minutes = sec_elapsed % 3600 / 60
var str_elapsed = "%02d : %02d" % [minutes, seconds]

get_node("GUI/Label").set_text(str(str_elapsed))

is it still workable after 03:14:07 UTC on 19 January 2038 ?

@ruruarchy I imagine that would depend on the 'OS' wrapper code. Godot uses 64-bit ints, so as long as the wrapper code puts in a 64-bit, we should be good.

I am trying to implement a timer which is in reverse, like, it checks whether current lives are less than total lives and refills a life after 15 minutes, with your code, I could get a timer going, but it shows the time in ascending order and its a string, can you help me to show it as a deduction per second from 15 minutes and how can I do something like
if elapsed >= 15 minutes: do something

That's a separate question... (But usually you would add delta to a variable every _process then check if it's over 15min and reset it back to 0 after doing your thang. You could make it so it resets to 0 if lives are missing.)

Could we add milliseconds to this?

Milliseconds are kinda a different beast. Unix epoch is an int of seconds, so no way to get ms there. You'd have to use a timer node or use OS.get_ticks_msec(). Timer node may be what you want if the game can pause, cuz you won't have to handle that yourself.

+1 vote

The other answer is grand if you don't need precision, and is likely more suitable if you want accurate "real" time elapsed over a very long period.

However, if you want your timer to stop during pauses, or re-launches of the game, or you want to mess with Engine.time_scale, or need more precise measurements in relation to in-game events (ie a second's lag in the time might put everything out of sync), then you need to work in relation to Godot's provided delta:

var time = 0

func _ready():
    time = 0

func _process(delta):
    time += delta
    var seconds = fmod(time,60)
    var minutes = fmod(time, 3600) / 60
    var str_elapsed = "%02d : %02d" % [minutes, seconds]
    print("elapsed : ", str_elapsed)

This has the added benefit of being simpler anyway, and of the resulting 'time' being natively returned as seconds.

If you you want to make calculations in relation to specific physics measurements (eg measuring something's average speed), then you're better off using _physics_process to add your deltas, as these will happen in sync with physics updates.

by (22 points)
edited by

You could also get milliseconds with: var ms = fmod(time,1)*1000.
The other answer uses OS.get_unix_time(), which only has second(s) precision. Using delta gets a more accurate time. (Note: If you can't do delta for some reason, you can tweak the other answer to use OS.get_ticks_msec() for milliseconds or OS.get_ticks_usec()for microseconds.)

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.