Feat/5 adding settings fundamentals and ui improvements #9
@@ -12,6 +12,7 @@ var _grapple_icon: TextureRect
|
|||||||
var _dash_icon: TextureRect
|
var _dash_icon: TextureRect
|
||||||
var _grapple_label: Label
|
var _grapple_label: Label
|
||||||
var _dash_label: Label
|
var _dash_label: Label
|
||||||
|
var _fps_label: Label
|
||||||
var _player: CharacterBody3D
|
var _player: CharacterBody3D
|
||||||
var _debug_ui_panel: PanelContainer
|
var _debug_ui_panel: PanelContainer
|
||||||
|
|
||||||
@@ -401,12 +402,23 @@ func _build_hud() -> void:
|
|||||||
crosshair.add_child(line)
|
crosshair.add_child(line)
|
||||||
|
|
||||||
# ── Info panel background ─────────────────────────────────────────────
|
# ── Info panel background ─────────────────────────────────────────────
|
||||||
|
_fps_label = Label.new()
|
||||||
|
_fps_label.name = "FPSLabel"
|
||||||
|
_fps_label.text = "FPS: 0"
|
||||||
|
_fps_label.add_theme_font_size_override("font_size", 24)
|
||||||
|
_fps_label.add_theme_color_override("font_color", Color(0.9, 0.9, 0.2))
|
||||||
|
_fps_label.add_theme_color_override("font_outline_color", Color(0, 0, 0))
|
||||||
|
_fps_label.add_theme_constant_override("outline_size", 4)
|
||||||
|
_fps_label.set_anchors_preset(Control.PRESET_TOP_LEFT)
|
||||||
|
_fps_label.position = Vector2(12, 12)
|
||||||
|
canvas.add_child(_fps_label)
|
||||||
|
|
||||||
_debug_ui_panel = PanelContainer.new()
|
_debug_ui_panel = PanelContainer.new()
|
||||||
_debug_ui_panel.name = "InfoPanel"
|
_debug_ui_panel.name = "InfoPanel"
|
||||||
_debug_ui_panel.offset_left = 12
|
_debug_ui_panel.offset_left = 12
|
||||||
_debug_ui_panel.offset_top = 12
|
_debug_ui_panel.offset_top = 50
|
||||||
_debug_ui_panel.offset_right = 400
|
_debug_ui_panel.offset_right = 400
|
||||||
_debug_ui_panel.offset_bottom = 120
|
_debug_ui_panel.offset_bottom = 160
|
||||||
var panel_style := StyleBoxFlat.new()
|
var panel_style := StyleBoxFlat.new()
|
||||||
panel_style.bg_color = Color(0, 0, 0, 0.55)
|
panel_style.bg_color = Color(0, 0, 0, 0.55)
|
||||||
panel_style.corner_radius_top_left = 8
|
panel_style.corner_radius_top_left = 8
|
||||||
@@ -564,6 +576,11 @@ func _process(_delta: float) -> void:
|
|||||||
if _debug_ui_panel:
|
if _debug_ui_panel:
|
||||||
_debug_ui_panel.visible = SettingsManager.show_debug_ui
|
_debug_ui_panel.visible = SettingsManager.show_debug_ui
|
||||||
|
|
||||||
|
if _fps_label:
|
||||||
|
_fps_label.visible = SettingsManager.show_fps
|
||||||
|
if _fps_label.visible:
|
||||||
|
_fps_label.text = "FPS: %d" % Engine.get_frames_per_second()
|
||||||
|
|
||||||
var vel: Vector3 = _player.velocity
|
var vel: Vector3 = _player.velocity
|
||||||
var hspeed := Vector2(vel.x, vel.z).length()
|
var hspeed := Vector2(vel.x, vel.z).length()
|
||||||
var total_speed := vel.length()
|
var total_speed := vel.length()
|
||||||
|
|||||||
@@ -26,6 +26,22 @@ var current_bindings = {}
|
|||||||
var show_debug_ui: bool = false
|
var show_debug_ui: bool = false
|
||||||
var mouse_sensitivity: float = 0.002
|
var mouse_sensitivity: float = 0.002
|
||||||
|
|
||||||
|
# Video Settings
|
||||||
|
var display_mode: int = DisplayServer.WINDOW_MODE_WINDOWED
|
||||||
|
var resolution_index: int = 2 # Default to 1920x1080
|
||||||
|
var fps_cap: int = 0
|
||||||
|
var show_fps: bool = false
|
||||||
|
|
||||||
|
var resolutions = [
|
||||||
|
Vector2i(640, 480), # 480p
|
||||||
|
Vector2i(1280, 720), # 720p
|
||||||
|
Vector2i(1920, 1080), # 1080p
|
||||||
|
Vector2i(2560, 1080), # UW-1080p
|
||||||
|
Vector2i(2560, 1440), # 1440p
|
||||||
|
Vector2i(3440, 1440), # UW-1440p
|
||||||
|
Vector2i(3840, 2160) # 4K
|
||||||
|
]
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
# Initialize defaults
|
# Initialize defaults
|
||||||
current_bindings = default_bindings.duplicate(true)
|
current_bindings = default_bindings.duplicate(true)
|
||||||
@@ -36,6 +52,9 @@ func _ready() -> void:
|
|||||||
# Apply to InputMap
|
# Apply to InputMap
|
||||||
_apply_all_bindings()
|
_apply_all_bindings()
|
||||||
|
|
||||||
|
# Apply Video Settings
|
||||||
|
apply_video_settings()
|
||||||
|
|
||||||
func _apply_all_bindings() -> void:
|
func _apply_all_bindings() -> void:
|
||||||
for action in current_bindings:
|
for action in current_bindings:
|
||||||
if not InputMap.has_action(action):
|
if not InputMap.has_action(action):
|
||||||
@@ -78,7 +97,11 @@ func _save_settings() -> void:
|
|||||||
var save_data = {
|
var save_data = {
|
||||||
"bindings": current_bindings,
|
"bindings": current_bindings,
|
||||||
"show_debug_ui": show_debug_ui,
|
"show_debug_ui": show_debug_ui,
|
||||||
"mouse_sensitivity": mouse_sensitivity
|
"mouse_sensitivity": mouse_sensitivity,
|
||||||
|
"display_mode": display_mode,
|
||||||
|
"resolution_index": resolution_index,
|
||||||
|
"fps_cap": fps_cap,
|
||||||
|
"show_fps": show_fps
|
||||||
}
|
}
|
||||||
var json_string = JSON.stringify(save_data)
|
var json_string = JSON.stringify(save_data)
|
||||||
var file = FileAccess.open(SAVE_PATH, FileAccess.WRITE)
|
var file = FileAccess.open(SAVE_PATH, FileAccess.WRITE)
|
||||||
@@ -107,3 +130,25 @@ func _load_settings() -> void:
|
|||||||
show_debug_ui = data["show_debug_ui"]
|
show_debug_ui = data["show_debug_ui"]
|
||||||
if data.has("mouse_sensitivity"):
|
if data.has("mouse_sensitivity"):
|
||||||
mouse_sensitivity = data["mouse_sensitivity"]
|
mouse_sensitivity = data["mouse_sensitivity"]
|
||||||
|
if data.has("display_mode"): display_mode = data["display_mode"]
|
||||||
|
if data.has("resolution_index"): resolution_index = data["resolution_index"]
|
||||||
|
if data.has("fps_cap"): fps_cap = data["fps_cap"]
|
||||||
|
if data.has("show_fps"): show_fps = data["show_fps"]
|
||||||
|
|
||||||
|
func apply_video_settings() -> void:
|
||||||
|
if display_mode == DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN:
|
||||||
|
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN)
|
||||||
|
elif display_mode == DisplayServer.WINDOW_MODE_FULLSCREEN:
|
||||||
|
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
|
||||||
|
else:
|
||||||
|
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
|
||||||
|
if resolution_index >= 0 and resolution_index < resolutions.size():
|
||||||
|
DisplayServer.window_set_size(resolutions[resolution_index])
|
||||||
|
# Center window on primary screen
|
||||||
|
var screen = DisplayServer.window_get_current_screen()
|
||||||
|
var screen_size = DisplayServer.screen_get_size(screen)
|
||||||
|
var window_size = DisplayServer.window_get_size()
|
||||||
|
# Simple centering heuristic
|
||||||
|
DisplayServer.window_set_position((screen_size - window_size) / 2)
|
||||||
|
|
||||||
|
Engine.max_fps = fps_cap
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ var settings_back_btn: Button
|
|||||||
var _debug_ui_checkbox: CheckButton
|
var _debug_ui_checkbox: CheckButton
|
||||||
var _mouse_sens_slider: HSlider
|
var _mouse_sens_slider: HSlider
|
||||||
var _mouse_sens_input: LineEdit
|
var _mouse_sens_input: LineEdit
|
||||||
|
var _display_mode_opt: OptionButton
|
||||||
|
var _resolution_opt: OptionButton
|
||||||
|
var _fps_slider: HSlider
|
||||||
|
var _fps_input: LineEdit
|
||||||
|
var _show_fps_checkbox: CheckButton
|
||||||
var keybind_vbox: VBoxContainer
|
var keybind_vbox: VBoxContainer
|
||||||
var rebind_overlay: ColorRect
|
var rebind_overlay: ColorRect
|
||||||
var rebind_label: Label
|
var rebind_label: Label
|
||||||
@@ -223,6 +228,117 @@ func _build_ui() -> void:
|
|||||||
)
|
)
|
||||||
general_tab.add_child(reset_gen_btn)
|
general_tab.add_child(reset_gen_btn)
|
||||||
|
|
||||||
|
# Video Tab
|
||||||
|
var video_tab = VBoxContainer.new()
|
||||||
|
video_tab.name = "Video"
|
||||||
|
video_tab.add_theme_constant_override("separation", 10)
|
||||||
|
tab_container.add_child(video_tab)
|
||||||
|
|
||||||
|
var mode_hbox = HBoxContainer.new()
|
||||||
|
video_tab.add_child(mode_hbox)
|
||||||
|
var mode_lbl = Label.new()
|
||||||
|
mode_lbl.text = "Display Mode"
|
||||||
|
mode_lbl.custom_minimum_size = Vector2(150, 0)
|
||||||
|
mode_hbox.add_child(mode_lbl)
|
||||||
|
_display_mode_opt = OptionButton.new()
|
||||||
|
_display_mode_opt.add_item("Windowed", DisplayServer.WINDOW_MODE_WINDOWED)
|
||||||
|
_display_mode_opt.add_item("Borderless Fullscreen", DisplayServer.WINDOW_MODE_FULLSCREEN)
|
||||||
|
_display_mode_opt.add_item("Exclusive Fullscreen", DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN)
|
||||||
|
_display_mode_opt.item_selected.connect(func(index: int):
|
||||||
|
SettingsManager.display_mode = _display_mode_opt.get_item_id(index)
|
||||||
|
SettingsManager._save_settings()
|
||||||
|
SettingsManager.apply_video_settings()
|
||||||
|
)
|
||||||
|
mode_hbox.add_child(_display_mode_opt)
|
||||||
|
|
||||||
|
var res_hbox = HBoxContainer.new()
|
||||||
|
video_tab.add_child(res_hbox)
|
||||||
|
var res_lbl = Label.new()
|
||||||
|
res_lbl.text = "Resolution"
|
||||||
|
res_lbl.custom_minimum_size = Vector2(150, 0)
|
||||||
|
res_hbox.add_child(res_lbl)
|
||||||
|
_resolution_opt = OptionButton.new()
|
||||||
|
var res_names = ["640x480 (480p)", "1280x720 (720p)", "1920x1080 (1080p)", "2560x1080 (UW-1080p)", "2560x1440 (1440p)", "3440x1440 (UW-1440p)", "3840x2160 (4K)"]
|
||||||
|
for i in range(res_names.size()):
|
||||||
|
_resolution_opt.add_item(res_names[i], i)
|
||||||
|
_resolution_opt.item_selected.connect(func(index: int):
|
||||||
|
SettingsManager.resolution_index = index
|
||||||
|
SettingsManager._save_settings()
|
||||||
|
SettingsManager.apply_video_settings()
|
||||||
|
)
|
||||||
|
res_hbox.add_child(_resolution_opt)
|
||||||
|
|
||||||
|
var fps_hbox = HBoxContainer.new()
|
||||||
|
video_tab.add_child(fps_hbox)
|
||||||
|
var fps_lbl = Label.new()
|
||||||
|
fps_lbl.text = "FPS Cap"
|
||||||
|
fps_lbl.custom_minimum_size = Vector2(150, 0)
|
||||||
|
fps_hbox.add_child(fps_lbl)
|
||||||
|
_fps_slider = HSlider.new()
|
||||||
|
_fps_slider.min_value = 30.0
|
||||||
|
_fps_slider.max_value = 361.0
|
||||||
|
_fps_slider.step = 1.0
|
||||||
|
_fps_slider.custom_minimum_size = Vector2(200, 0)
|
||||||
|
_fps_slider.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||||
|
fps_hbox.add_child(_fps_slider)
|
||||||
|
_fps_input = LineEdit.new()
|
||||||
|
_fps_input.custom_minimum_size = Vector2(80, 0)
|
||||||
|
fps_hbox.add_child(_fps_input)
|
||||||
|
_fps_slider.value_changed.connect(func(value: float):
|
||||||
|
if value > 360.0:
|
||||||
|
_fps_input.text = "Uncapped"
|
||||||
|
SettingsManager.fps_cap = 0
|
||||||
|
else:
|
||||||
|
_fps_input.text = str(int(value))
|
||||||
|
SettingsManager.fps_cap = int(value)
|
||||||
|
SettingsManager._save_settings()
|
||||||
|
SettingsManager.apply_video_settings()
|
||||||
|
)
|
||||||
|
_fps_input.text_submitted.connect(func(new_text: String):
|
||||||
|
var val = new_text.to_int()
|
||||||
|
if val > 360 or val <= 0:
|
||||||
|
_fps_slider.value = 361.0
|
||||||
|
_fps_input.text = "Uncapped"
|
||||||
|
SettingsManager.fps_cap = 0
|
||||||
|
else:
|
||||||
|
val = max(30, val)
|
||||||
|
_fps_slider.value = float(val)
|
||||||
|
_fps_input.text = str(val)
|
||||||
|
SettingsManager.fps_cap = val
|
||||||
|
SettingsManager._save_settings()
|
||||||
|
SettingsManager.apply_video_settings()
|
||||||
|
)
|
||||||
|
|
||||||
|
var spacer_vid = Control.new()
|
||||||
|
spacer_vid.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||||
|
video_tab.add_child(spacer_vid)
|
||||||
|
var reset_vid_btn = Button.new()
|
||||||
|
reset_vid_btn.text = "Reset to Defaults"
|
||||||
|
reset_vid_btn.pressed.connect(func():
|
||||||
|
SettingsManager.display_mode = DisplayServer.WINDOW_MODE_WINDOWED
|
||||||
|
SettingsManager.resolution_index = 2
|
||||||
|
SettingsManager.fps_cap = 0
|
||||||
|
SettingsManager._save_settings()
|
||||||
|
SettingsManager.apply_video_settings()
|
||||||
|
_populate_video_ui()
|
||||||
|
)
|
||||||
|
video_tab.add_child(reset_vid_btn)
|
||||||
|
|
||||||
|
# Audio Tab
|
||||||
|
var audio_tab = VBoxContainer.new()
|
||||||
|
audio_tab.name = "Audio"
|
||||||
|
tab_container.add_child(audio_tab)
|
||||||
|
var aud_label = Label.new()
|
||||||
|
aud_label.text = "Settings coming soon..."
|
||||||
|
audio_tab.add_child(aud_label)
|
||||||
|
var spacer_aud = Control.new()
|
||||||
|
spacer_aud.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||||
|
audio_tab.add_child(spacer_aud)
|
||||||
|
var reset_aud_btn = Button.new()
|
||||||
|
reset_aud_btn.text = "Reset to Defaults"
|
||||||
|
reset_aud_btn.pressed.connect(func(): pass)
|
||||||
|
audio_tab.add_child(reset_aud_btn)
|
||||||
|
|
||||||
# Mouse Tab
|
# Mouse Tab
|
||||||
var mouse_tab = VBoxContainer.new()
|
var mouse_tab = VBoxContainer.new()
|
||||||
mouse_tab.name = "Mouse"
|
mouse_tab.name = "Mouse"
|
||||||
@@ -320,6 +436,15 @@ func _build_ui() -> void:
|
|||||||
)
|
)
|
||||||
advanced_tab.add_child(_debug_ui_checkbox)
|
advanced_tab.add_child(_debug_ui_checkbox)
|
||||||
|
|
||||||
|
_show_fps_checkbox = CheckButton.new()
|
||||||
|
_show_fps_checkbox.text = "Show FPS Counter"
|
||||||
|
_show_fps_checkbox.button_pressed = SettingsManager.show_fps
|
||||||
|
_show_fps_checkbox.toggled.connect(func(toggled_on: bool):
|
||||||
|
SettingsManager.show_fps = toggled_on
|
||||||
|
SettingsManager._save_settings()
|
||||||
|
)
|
||||||
|
advanced_tab.add_child(_show_fps_checkbox)
|
||||||
|
|
||||||
var spacer_adv = Control.new()
|
var spacer_adv = Control.new()
|
||||||
spacer_adv.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
spacer_adv.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||||
advanced_tab.add_child(spacer_adv)
|
advanced_tab.add_child(spacer_adv)
|
||||||
@@ -329,6 +454,8 @@ func _build_ui() -> void:
|
|||||||
reset_adv_btn.pressed.connect(func():
|
reset_adv_btn.pressed.connect(func():
|
||||||
_debug_ui_checkbox.button_pressed = false
|
_debug_ui_checkbox.button_pressed = false
|
||||||
SettingsManager.show_debug_ui = false
|
SettingsManager.show_debug_ui = false
|
||||||
|
_show_fps_checkbox.button_pressed = false
|
||||||
|
SettingsManager.show_fps = false
|
||||||
SettingsManager._save_settings()
|
SettingsManager._save_settings()
|
||||||
)
|
)
|
||||||
advanced_tab.add_child(reset_adv_btn)
|
advanced_tab.add_child(reset_adv_btn)
|
||||||
@@ -384,13 +511,32 @@ func _show_loadouts() -> void:
|
|||||||
edit_panel.visible = false
|
edit_panel.visible = false
|
||||||
_populate_loadout_list()
|
_populate_loadout_list()
|
||||||
|
|
||||||
|
func _populate_video_ui() -> void:
|
||||||
|
if _display_mode_opt:
|
||||||
|
for i in range(_display_mode_opt.item_count):
|
||||||
|
if _display_mode_opt.get_item_id(i) == SettingsManager.display_mode:
|
||||||
|
_display_mode_opt.select(i)
|
||||||
|
break
|
||||||
|
if _resolution_opt:
|
||||||
|
_resolution_opt.select(SettingsManager.resolution_index)
|
||||||
|
if _fps_slider and _fps_input:
|
||||||
|
if SettingsManager.fps_cap == 0:
|
||||||
|
_fps_slider.value = 361.0
|
||||||
|
_fps_input.text = "Uncapped"
|
||||||
|
else:
|
||||||
|
_fps_slider.value = float(SettingsManager.fps_cap)
|
||||||
|
_fps_input.text = str(SettingsManager.fps_cap)
|
||||||
|
|
||||||
func _show_settings() -> void:
|
func _show_settings() -> void:
|
||||||
main_vbox.visible = false
|
main_vbox.visible = false
|
||||||
loadout_editor.visible = false
|
loadout_editor.visible = false
|
||||||
settings_editor.visible = true
|
settings_editor.visible = true
|
||||||
_populate_keybindings()
|
_populate_keybindings()
|
||||||
|
_populate_video_ui()
|
||||||
if _debug_ui_checkbox:
|
if _debug_ui_checkbox:
|
||||||
_debug_ui_checkbox.button_pressed = SettingsManager.show_debug_ui
|
_debug_ui_checkbox.button_pressed = SettingsManager.show_debug_ui
|
||||||
|
if _show_fps_checkbox:
|
||||||
|
_show_fps_checkbox.button_pressed = SettingsManager.show_fps
|
||||||
if _mouse_sens_slider:
|
if _mouse_sens_slider:
|
||||||
var display_val = round(SettingsManager.mouse_sensitivity * 10000.0)
|
var display_val = round(SettingsManager.mouse_sensitivity * 10000.0)
|
||||||
_mouse_sens_slider.value = display_val
|
_mouse_sens_slider.value = display_val
|
||||||
|
|||||||
Reference in New Issue
Block a user