0

I want to make a timer function in Godot that would use the computers frame rate in order to run code at whatever fps I choose (ex. 60 fps). So far I have code for a basic timer:

var t = Timer.new()
t.set_wait_time(time)
t.set_one_shot(true)
self.add_child(t)
t.start()
yield(t, "timeout")
t.queue_free()

However rather than having the time variable be a set number, I would like it to change based on how fast the computer can run, or time between frames.

Joe
  • 345
  • 1
  • 14

1 Answers1

3

I want to make a timer function in Godot that would use the computers frame rate

That would be code in _process. If you have VSync enabled in project settings (Under Display -> Window -> Vsync, it is enabled by default), _process will run once per frame.

run code at whatever fps I choose (ex. 60 fps)

Then that is not the computer frame rate, but the one you say. For that you can use _physics_process, and configure the rate in project settings (Under Physics -> Common -> Physics Fps, it is 60 by default).


If what you want is to have something run X times each frame, then I'm going to suggest just calling it X times either in _process or _physics_process depending on your needs.

I would like it to change based on (...) time between frames.

You could also use delta to know the time between frame and decide based on that how many times to run your code.


If you want to use a Timer, you can set the process_mode to Physics to tie it to the physics frame rate. Idle will use the graphics frame rate.


From your code it appear you don't want to connect to the "timeout" signal, but yield instead. In that case, you might be interested in:

yield(get_tree(), "idle_frame")

Which will resume execution the next graphics frame.

Or…

yield(get_tree(), "physics_frame")

Which will resume execution the next physics frame.

Heck, by doing that, you can put all your logic on _ready and don't use _process or _physics_process at all. I don't recommend it, of course.


If you want a faster rate than the graphics and physics frames, then I suggest you check OS.get_ticks_msec or OS.get_ticks_usec to decide when to use yield.


Assuming you want to avoid both physics and graphics frames entirely, you can instead create a Thread and have it sleep with OS.delay_msec or OS.delay_usec. For abstract, you would do an infinite loop, call a delay each iteration, and then do whatever you want to do.

I made an stopwatch class for an answer on Gamedev that you may use or base your code on. It has a "tick" signal, and measure running time, with support for pausing, resuming, stopping and starting again. It is NOT optimized for short intervals. Its design goal was to archive a lower rate with lower CPU usage than just checking the time each frame.


I would like it to change based on how fast the computer can run

If you se a Thread with an infinite loop, and no delays… Well, it will run as fast as it can run.

Theraot
  • 31,890
  • 5
  • 57
  • 86