feat: gameplay settings screen (deadzone + sensitivity)
This commit is contained in:
97
objects/ui/gameplay_settings.tscn
Normal file
97
objects/ui/gameplay_settings.tscn
Normal file
@@ -0,0 +1,97 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://gameplay_settings_scene"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://gameplay_settings_script" path="res://scripts/UI/GameplaySettings.cs" id="1_gameplay"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_gameplay"]
|
||||
bg_color = Color(0, 0, 0, 1)
|
||||
|
||||
[node name="Gameplay Settings" type="Control" node_paths=PackedStringArray("DeadzoneSlider", "DeadzoneValueLabel", "SensitivitySlider", "SensitivityValueLabel", "GameplaySettingsControl")]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
script = ExtResource("1_gameplay")
|
||||
DeadzoneSlider = NodePath("PanelContainer/MarginContainer/VBoxContainer/Deadzone/HSlider")
|
||||
DeadzoneValueLabel = NodePath("PanelContainer/MarginContainer/VBoxContainer/Deadzone/HBoxContainer/DeadzoneValueLabel")
|
||||
SensitivitySlider = NodePath("PanelContainer/MarginContainer/VBoxContainer/Sensitivity/HSlider")
|
||||
SensitivityValueLabel = NodePath("PanelContainer/MarginContainer/VBoxContainer/Sensitivity/HBoxContainer/SensitivityValueLabel")
|
||||
GameplaySettingsControl = NodePath(".")
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_gameplay")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
|
||||
[node name="Gameplay" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "GAMEPLAY"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
uppercase = true
|
||||
|
||||
[node name="Spacer" type="Control" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 32)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Deadzone" type="VBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 4
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer/Deadzone"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="DeadzoneLabel" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer/Deadzone/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "GAMEPAD_DEADZONE"
|
||||
|
||||
[node name="DeadzoneValueLabel" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer/Deadzone/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "0.20"
|
||||
|
||||
[node name="HSlider" type="HSlider" parent="PanelContainer/MarginContainer/VBoxContainer/Deadzone"]
|
||||
custom_minimum_size = Vector2(64, 0)
|
||||
layout_mode = 2
|
||||
value = 0.2
|
||||
|
||||
[node name="Sensitivity" type="VBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 4
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer/Sensitivity"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SensitivityLabel" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer/Sensitivity/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "GAMEPAD_SENSITIVITY"
|
||||
|
||||
[node name="SensitivityValueLabel" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer/Sensitivity/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "1.00"
|
||||
|
||||
[node name="HSlider" type="HSlider" parent="PanelContainer/MarginContainer/VBoxContainer/Sensitivity"]
|
||||
custom_minimum_size = Vector2(64, 0)
|
||||
layout_mode = 2
|
||||
value = 1.0
|
||||
@@ -68,7 +68,6 @@ flat = true
|
||||
|
||||
[node name="Gameplay Settings Button" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
disabled = true
|
||||
text = "GAMEPLAY_BUTTON"
|
||||
flat = true
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://cl00e2ocomk3m"]
|
||||
[gd_scene load_steps=8 format=3 uid="uid://cl00e2ocomk3m"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://8b6ol5sssbgo" path="res://objects/ui/main_menu.tscn" id="1_ekxnf"]
|
||||
[ext_resource type="PackedScene" uid="uid://y0ae6e7t70fj" path="res://objects/ui/settings_menu.tscn" id="2_bqqt6"]
|
||||
@@ -6,6 +6,7 @@
|
||||
[ext_resource type="PackedScene" uid="uid://b5fx1vdfky307" path="res://objects/ui/audio_settings.tscn" id="4_8ln24"]
|
||||
[ext_resource type="PackedScene" uid="uid://cvfsbiy5ggrpg" path="res://objects/ui/input_settings.tscn" id="5_rtw2f"]
|
||||
[ext_resource type="PackedScene" uid="uid://display_settings_scene" path="res://objects/ui/display_settings.tscn" id="6_dispset"]
|
||||
[ext_resource type="PackedScene" uid="uid://gameplay_settings_scene" path="res://objects/ui/gameplay_settings.tscn" id="7_gameplay"]
|
||||
|
||||
[node name="Main menu" type="CanvasLayer"]
|
||||
|
||||
@@ -29,11 +30,8 @@ visible = false
|
||||
[node name="Input Settings" parent="." instance=ExtResource("5_rtw2f")]
|
||||
visible = false
|
||||
|
||||
[node name="Gameplay Settings" type="Control" parent="."]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
[node name="Gameplay Settings" parent="." instance=ExtResource("7_gameplay")]
|
||||
visible = false
|
||||
|
||||
[node name="Display Settings" parent="." instance=ExtResource("6_dispset")]
|
||||
visible = false
|
||||
|
||||
101
scripts/UI/GameplaySettings.cs
Normal file
101
scripts/UI/GameplaySettings.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class GameplaySettings : Control
|
||||
{
|
||||
[Export] public HSlider DeadzoneSlider { get; set; }
|
||||
[Export] public Label DeadzoneValueLabel { get; set; }
|
||||
[Export] public HSlider SensitivitySlider { get; set; }
|
||||
[Export] public Label SensitivityValueLabel { get; set; }
|
||||
[Export] public Control GameplaySettingsControl { get; set; }
|
||||
|
||||
private UIManager UIManager => UIManager.Instance;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
DeadzoneSlider.FocusMode = Control.FocusModeEnum.All;
|
||||
SensitivitySlider.FocusMode = Control.FocusModeEnum.All;
|
||||
|
||||
DeadzoneSlider.MinValue = 0.05;
|
||||
DeadzoneSlider.MaxValue = 0.5;
|
||||
DeadzoneSlider.Step = 0.05;
|
||||
DeadzoneSlider.Value = 0.2;
|
||||
|
||||
SensitivitySlider.MinValue = 0.5;
|
||||
SensitivitySlider.MaxValue = 2.0;
|
||||
SensitivitySlider.Step = 0.1;
|
||||
SensitivitySlider.Value = 1.0;
|
||||
|
||||
LoadSettings();
|
||||
|
||||
DeadzoneSlider.ValueChanged += OnDeadzoneChanged;
|
||||
SensitivitySlider.ValueChanged += OnSensitivityChanged;
|
||||
|
||||
if (InputDeviceManager.Instance != null)
|
||||
InputDeviceManager.Instance.DeviceChanged += OnDeviceChanged;
|
||||
GameplaySettingsControl.VisibilityChanged += OnVisibilityChanged;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
if (InputDeviceManager.Instance != null)
|
||||
InputDeviceManager.Instance.DeviceChanged -= OnDeviceChanged;
|
||||
GameplaySettingsControl.VisibilityChanged -= OnVisibilityChanged;
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (!@event.IsActionReleased("ui_cancel")) return;
|
||||
if (!UIManager.IsScreenOnTop(GameplaySettingsControl)) return;
|
||||
|
||||
SaveSettings();
|
||||
UIManager.PopScreen();
|
||||
}
|
||||
|
||||
private void OnVisibilityChanged()
|
||||
{
|
||||
if (GameplaySettingsControl.IsVisibleInTree() && InputDeviceManager.Instance?.IsPointerless == true)
|
||||
GrabFirstFocus();
|
||||
}
|
||||
|
||||
private void OnDeviceChanged(int device)
|
||||
{
|
||||
var d = (InputDeviceManager.InputDevice)device;
|
||||
if (d != InputDeviceManager.InputDevice.Mouse && GameplaySettingsControl.IsVisibleInTree())
|
||||
GrabFirstFocus();
|
||||
}
|
||||
|
||||
private void GrabFirstFocus() => DeadzoneSlider.GrabFocus();
|
||||
|
||||
private void OnDeadzoneChanged(double value)
|
||||
{
|
||||
SettingsManager.Instance.GamepadDeadzone = (float)value;
|
||||
foreach (var action in new[] { "left", "right", "up", "down" })
|
||||
{
|
||||
if (InputMap.HasAction(action))
|
||||
InputMap.ActionSetDeadzone(action, (float)value);
|
||||
}
|
||||
DeadzoneValueLabel.Text = $"{value:F2}";
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
private void OnSensitivityChanged(double value)
|
||||
{
|
||||
SettingsManager.Instance.GamepadSensitivity = (float)value;
|
||||
SensitivityValueLabel.Text = $"{value:F2}";
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
DeadzoneSlider.Value = SettingsManager.Instance.GamepadDeadzone;
|
||||
SensitivitySlider.Value = SettingsManager.Instance.GamepadSensitivity;
|
||||
DeadzoneValueLabel.Text = $"{SettingsManager.Instance.GamepadDeadzone:F2}";
|
||||
SensitivityValueLabel.Text = $"{SettingsManager.Instance.GamepadSensitivity:F2}";
|
||||
}
|
||||
|
||||
private void SaveSettings() => SettingsManager.Instance.SaveGameplaySettings();
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
@@ -15,7 +16,11 @@ public partial class PlayerInputHandler : Node
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
MoveDirection = Input.GetVector("left", "right", "up", "down");
|
||||
var rawInput = Input.GetVector("left", "right", "up", "down");
|
||||
var sensitivity = SettingsManager.Instance?.GamepadSensitivity ?? 1.0f;
|
||||
MoveDirection = rawInput.Length() > 0
|
||||
? rawInput.Normalized() * Mathf.Min(rawInput.Length() * sensitivity, 1.0f)
|
||||
: Vector2.Zero;
|
||||
|
||||
JumpPressed = Input.IsActionJustPressed("jump");
|
||||
JumpReleased = Input.IsActionJustReleased("jump");
|
||||
|
||||
Reference in New Issue
Block a user