Is there a signal called every time a scene stabilizes?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By fabiodellaria

With each loading of a new scene, I noticed that Godot takes from a few tenths to a few seconds to stabilize at 60 FPS.

To check if the graphics effects of my game slow down too much (lowering the FPS below 60), I wait 5 seconds from the start of the scene and then check the average FPS. If the FPS is lower than 60, I disable the graphic effects.

I wanted to know if there is a signal called every time a scene is stabilized, so as not to wait for 5 seconds anymore but to use this signal directly.

Thank you

:bust_in_silhouette: Reply From: Bernard Cloutier

No, but you can add the following node:

extends Node

signal framerate_sabilized
 
var _is_framerate_stable := false

func _process(_delta):
    if Engine.get_frames_per_second() > 60.0:
        if not _is_framerate_stable:
            _is_framerate_stable = true
            emit_signal("framerate_sabilized")
    else:
        _is_framerate_stable = false

No, I’m sorry.
This do not solve the problem, because in low-end devices the siglan will never be raised and FPS will be always < 60. I need the signal is raised NOT when FPS > 60, but when Godot finish its initial stabilition work on the just loaded scene. So… at this time… I can test the FPS and see if the current device and the current game configuration will allow to obtain a stable 60 FPS.

fabiodellaria | 2022-08-11 14:56

Then you can check the variation of the framerate, and emit the signal when it’s stable. Ex:

extends Node

signal framerate_sabilized

export(float) var min_framerate_variation = 1.0
export(float) var check_delay = 0.5

var _last_fps = 0.0
var _variation = 0.0
var _is_stable = false

func _ready():
    var tween = create_tween().set_loops()
    tween.tween_callback(self, "check_framerate_stable").set_delay(check_delay)

func _process(_delta):
    var fps = Engine.get_frames_per_second()
    _variation += abs(fps - _last_fps)
    _last_fps = fps
        
func check_framerate_stable():
    if _variation / check_delay < min_framerate_variation:
        if not _is_stable:
            _is_stable = true
            emit_signal("framerate_sabilized")
    else:
        _is_stable = false
    _variation = 0.0

Edit: I realized too late that you are not on Godot 3.5, so you can’t use the SceneTreeTween like in my code. Just use a timer instead with oneshot = false.

Bernard Cloutier | 2022-08-11 15:46

Thanks a lot, this seems to be a good way,I’ll test it. :slight_smile:

fabiodellaria | 2022-08-12 07:56