Godot Version
Godot 4.5.1 stable official
Question
when I run the game my fps gets stuck to around 50 and then when I pause and unpause then only fps goes to 100, I can see the effect of settings like disabled shadows with 0 after start without pause and unpause, but the fps only fix after pause and unpause !
SettingsScreen:
settings_screen.gd:
class_name SettingsScreen extends Control
## Vars
@export var debug : bool = false
@export_group("Graphics")
@export_subgroup("graphic_refs")
@export var resolution_opt : OptionButton
@export var window_opt : OptionButton
@export var vsync_opt : OptionButton
@export var shadow_opt : OptionButton
@export var render_scale_slider : HSlider
var settings_config : ConfigFile = ConfigFile.new()
var config_path : String = "user://config/settings.cfg"
var config_is_loading : bool = false
var config_display_section : String = "Display"
var config_graphics_section : String = "Graphics"
const resolution_data : Dictionary = {
"def": { "id": "resolution", "data": Vector2i(1280, 720), "value": 0 },
0: { "id": "resolution", "data": Vector2i(1280, 720) },
1: { "id": "resolution", "data": Vector2i(1900, 1600) },
2: { "id": "resolution", "data": Vector2i(1920, 1280) }
}
const window_data : Dictionary = {
"def": { "id": "fullscreen", "data": DisplayServer.WINDOW_MODE_MAXIMIZED, "value": 1 },
0: { "id": "fullscreen", "data": DisplayServer.WINDOW_MODE_WINDOWED, "name": "Windowed" },
1: { "id": "fullscreen", "data": DisplayServer.WINDOW_MODE_MAXIMIZED, "name": "Maximized" },
2: { "id": "fullscreen", "data": DisplayServer.WINDOW_MODE_FULLSCREEN, "name": "Fullscreen" },
}
const vsync_data : Dictionary = {
"def": { "id": "vsync", "data": DisplayServer.VSYNC_ENABLED, "value": 1 },
0: { "id": "vsync", "data": DisplayServer.VSYNC_DISABLED, "name": "Disabled" },
1: { "id": "vsync", "data": DisplayServer.VSYNC_ENABLED, "name": "Enabled" },
2: { "id": "vsync", "data": DisplayServer.VSYNC_ADAPTIVE, "name": "Adaptive" }
}
const shadow_data : Dictionary = {
"def": { "id": "shadow", "data": 4096, "value": 2 },
0: { "id": "shadow", "data": 0, "name": "Disabled" },
1: { "id": "shadow", "data": 2048, "name": "Low" },
2: { "id": "shadow", "data": 4096, "name": "Medium" },
3: { "id": "shadow", "data": 8192, "name": "High" },
}
const render_scale_data : Dictionary = {
"def": { "id": "render_scale", "data": 1.0, "value": 1.0 }
}
### Mains
func _ready() -> void:
self.process_mode = Node.PROCESS_MODE_ALWAYS
_connect_signals()
_make_or_load_config()
func _unhandled_input(event: InputEvent) -> void:
if Input.is_action_just_pressed("p1_ctrl"):
self.visible = !self.visible
### UseCallables
## Func
func save_setting(section: String, key: String, value) -> void:
if config_is_loading:
return
settings_config.load(config_path)
settings_config.set_value(section, key, value)
settings_config.save(config_path)
func log_debug(id: String, value, always_print: bool = false) -> void:
if always_print:
print( str("Debug: ", self.name, ": ", id, " = ", value) )
else:
if debug:
print( str("Debug: ", self.name, ": ", id, " = ", value) )
### Usables
## Ready
func _connect_signals() -> void:
# Dispaly
resolution_opt.item_selected.connect(_on_resolution_opt_selected)
window_opt.item_selected.connect(_on_window_opt_selected)
vsync_opt.item_selected.connect(_on_vsync_opt_selected)
# Graphics
render_scale_slider.value_changed.connect(_on_render_scale_changed)
shadow_opt.item_selected.connect(_on_shadow_opt_selected)
func _make_or_load_config() -> void:
var user_dir := DirAccess.open("user://")
if not user_dir.dir_exists("config"):
user_dir.make_dir("config")
if FileAccess.file_exists(config_path):
_load_config()
else:
_make_default_config()
## Func
func _make_default_config() -> void:
settings_config.set_value(config_display_section, resolution_data["def"]["id"], resolution_data["def"]["value"])
settings_config.set_value(config_display_section, window_data["def"]["id"], window_data["def"]["value"])
settings_config.set_value(config_display_section, vsync_data["def"]["id"], vsync_data["def"]["value"])
settings_config.set_value(config_graphics_section, render_scale_data["def"]["id"], render_scale_data["def"]["value"])
settings_config.set_value(config_graphics_section, shadow_data["def"]["id"], shadow_data["def"]["value"])
settings_config.save(config_path)
log_debug("default_config_created", "true", true)
func _load_config() -> void:
config_is_loading = true
settings_config.load(config_path)
var res_index = settings_config.get_value(config_display_section, resolution_data["def"]["id"], resolution_data["def"]["value"])
resolution_opt.select(res_index)
_on_resolution_opt_selected(res_index)
var win_index = settings_config.get_value(config_display_section, window_data["def"]["id"], window_data["def"]["value"])
window_opt.select(win_index)
_on_window_opt_selected(win_index)
var vsync_index = settings_config.get_value(config_display_section, vsync_data["def"]["id"], vsync_data["def"]["value"])
vsync_opt.select(vsync_index)
_on_vsync_opt_selected(vsync_index)
var scale = settings_config.get_value(config_graphics_section, render_scale_data["def"]["id"], render_scale_data["def"]["value"])
render_scale_slider.value = scale
_on_render_scale_changed(scale)
var shadow_index = settings_config.get_value(config_graphics_section, shadow_data["def"]["id"], shadow_data["def"]["value"])
shadow_opt.select(shadow_index)
_on_shadow_opt_selected(shadow_index)
config_is_loading = false
log_debug("config_loaded", "true", true)
### Signals
## Display
func _on_resolution_opt_selected(index: int) -> void:
var dict = resolution_data[index]
DisplayServer.window_set_size(dict["data"])
save_setting(config_display_section, dict["id"], index)
log_debug(dict["id"], dict["data"])
func _on_window_opt_selected(index: int) -> void:
var dict = window_data[index]
DisplayServer.window_set_mode(dict["data"])
save_setting(config_display_section, dict["id"], index)
log_debug(dict["id"], dict["name"])
func _on_vsync_opt_selected(index: int) -> void:
var dict = vsync_data[index]
DisplayServer.window_set_vsync_mode(dict["data"])
save_setting(config_display_section, dict["id"], index)
log_debug(dict["id"], dict["name"])
## Graphics
func _on_render_scale_changed(value: float) -> void:
var viewport := get_viewport()
var sub_viewports := get_tree().get_nodes_in_group(GlobalVarHandler.Group.Group_SubViewPort)
viewport.scaling_3d_scale = value
for sv in sub_viewports:
sv.scaling_3d_scale = value
save_setting(config_graphics_section, "render_scale", value)
log_debug("render_scale", value)
func _on_shadow_opt_selected(index: int) -> void:
var dict = shadow_data[index]
RenderingServer.directional_shadow_atlas_set_size(dict["data"], true)
save_setting(config_graphics_section, dict["id"], index)
log_debug(dict["id"], dict["name"])
GameUI:
game_ui.gd:
class_name GameUI extends CanvasLayer
## Vars
@export_group("uis")
@export var main_ui : Node
@export_group("screens")
@export var game_over_screen : Control
@export var pause_screen : Control
@export var settings_screen : Control
@export_group("buttons")
@export var pause_resume_button : Button
@export var pause_settings_button : Button
@export var pause_close_button : Button
var player_count : int = 0
### Mains
func _ready() -> void:
_ready_game_ui()
_connect_signals()
func _unhandled_input(event: InputEvent) -> void:
_get_input(event)
### Usables
## Ready
func _ready_game_ui() -> void:
self.process_mode = Node.PROCESS_MODE_ALWAYS
main_ui.process_mode = Node.PROCESS_MODE_ALWAYS
layer = 100
game_over_screen.hide()
settings_screen.hide()
pause_screen.hide()
func _connect_signals() -> void:
# Screens
GlobalSignalHandler.all_players_died.connect(_update_game_over_screen)
# Buttons
pause_resume_button.pressed.connect(_on_pause_resume_button_pressed)
pause_settings_button.pressed.connect(_on_pause_settings_button_pressed)
pause_close_button.pressed.connect(_on_pause_close_button_pressed)
## Input
func _get_input(_event: InputEvent) -> void:
# Pause Screen
if Input.is_action_just_pressed(GlobalVarHandler.KeyBind.Escape):
#get_tree().quit()
pause_screen.visible = !pause_screen.visible
if pause_screen.is_visible_in_tree():
get_tree().paused = true
settings_screen.hide()
else:
get_tree().paused = false
### Signals
## Screens
func _update_game_over_screen() -> void:
print("game over")
game_over_screen.show()
## Buttons
func _on_pause_resume_button_pressed() -> void:
get_tree().paused = false
pause_screen.hide()
func _on_pause_settings_button_pressed() -> void:
pause_screen.hide()
settings_screen.show()
func _on_pause_close_button_pressed() -> void:
get_tree().quit()
settings.cfg:
[Display]
resolution=0
fullscreen=1
vsync=0
[Graphics]
render_scale=1.0
shadow=0
more reference:
Profiler:
first one is before pause & unpause with around 50 fps and second one is after pause and unpause with around 100 fps !
and now after sometime
After some testing i got to know that issue only appears when 3d world is in a SubViewPort !
but still couldnt find any fix except for doing pause and unpause every time the game starts
does anyone knows any fix to this ?
Thank you for your time and help !









