diff --git a/assets/text/text.csv b/assets/text/text.csv index 84de66a..1573392 100644 --- a/assets/text/text.csv +++ b/assets/text/text.csv @@ -21,13 +21,14 @@ PAUSE_QUIT_MSG,"Quit to desktop?\nUnsaved progress will be lost." SETTINGS_GAME,Game SETTINGS_GAME_HEADING,"Game Configuration" SETTINGS_GAME_ACCESSIBILITY_HEADING,Accessibility -SETTINGS_GAME_CAMERA_HEADING,Camera +SETTINGS_GAME_INPUT_HEADING,Input SETTINGS_SCREEN_SHAKE,"Enable Screen Shake" SETTINGS_HEAD_BOB,"Enable Head Bob" SETTINGS_SENSITIVITY_X,"Sensitivity, Horizontal" SETTINGS_SENSITIVITY_Y,"Sensitivity, Vertical" SETTINGS_MOUSE_ACCELERATION,"Mouse Acceleration" SETTINGS_INVERT_PITCH,"Invert Pitch" +SETTINGS_HOLD_TO_SNEAK,"Hold to Sneak" SETTINGS_GRAPHICS,Graphics SETTINGS_GRAPHICS_HEADING,"Graphics & Display" SETTINGS_GRAPHICS_DISPLAY_HEADING,Display diff --git a/project.godot b/project.godot index dc8cf03..554d7bc 100644 --- a/project.godot +++ b/project.godot @@ -71,6 +71,7 @@ config/input/mouse_acceleration=30.0 audio/buses/override_bus_layout="user://audio_bus_layout.tres" config/accessibility/enable_screen_shake=true config/accessibility/enable_head_bob=true +config/input/hold_to_sneak=true [global_group] diff --git a/src/game/game_settings.gd b/src/game/game_settings.gd index f37324e..6e851c0 100644 --- a/src/game/game_settings.gd +++ b/src/game/game_settings.gd @@ -10,6 +10,7 @@ var mouse_sensitivity_x: float var mouse_sensitivity_y: float var mouse_acceleration: float var invert_pitch: bool +var hold_to_sneak: bool var enable_screen_shake: bool var enable_head_bob: bool @@ -31,6 +32,7 @@ func _read_settings() -> void: mouse_sensitivity_y = ProjectSettings.get_setting("game/config/input/mouse_sensitivity_y") mouse_acceleration = ProjectSettings.get_setting("game/config/input/mouse_acceleration") invert_pitch = ProjectSettings.get_setting("game/config/input/invert_pitch") + hold_to_sneak = ProjectSettings.get_setting("game/config/input/hold_to_sneak") enable_screen_shake = ProjectSettings.get_setting( "game/config/accessibility/enable_screen_shake" diff --git a/src/player/player.gd b/src/player/player.gd index 03a5523..4d5cff3 100644 --- a/src/player/player.gd +++ b/src/player/player.gd @@ -1,17 +1,29 @@ class_name Player extends CharacterBody3D -const FOCUS_SPEED := 30.0 -const RUN_SPEED := 80.0 -const SPRINT_SPEED := 160.0 -const AIR_SPEED := 10.0 +#region Exported Properties -const JUMP_FORCE := 4.5 +@export_category("Movement") +@export_group("Speed") +@export var run_speed := 80.0 +@export var sprint_speed := 160.0 +@export var sneak_speed := 40.0 +@export var focus_speed := 25.0 +@export var air_speed_factor := 0.1 -const GROUND_FRICTION := 0.3 -const AIR_FRICTION := 0.03 +@export_group("Jump") +@export var jump_force := 4.0 +@export_group("Friction") +@export var ground_friction := 0.3 +@export var air_friction := 0.03 + +@export_category("Inventory") @export var inventory: Dictionary[Item, int] = {} +#endregion + +#region Member Variables + var gravity: Vector3 = ( ProjectSettings.get_setting("physics/3d/default_gravity") * ProjectSettings.get_setting("physics/3d/default_gravity_vector") @@ -19,6 +31,7 @@ var gravity: Vector3 = ( var selected_interactive: Interactive var firing := false +var crouching := false @onready var hud: PlayerHUD = %PlayerHUD @@ -31,28 +44,43 @@ var firing := false @onready var wide_spray: WideSpray = %WideSpray @onready var toothbrush: Tool = %Toothbrush +@onready var crouch_head_area: Area3D = %CrouchHeadArea +@onready var crouch_animation: AnimationPlayer = %CrouchAnimation + +#endregion + ## Global static access to player singleton static var instance: Player +#region _ready + func _ready() -> void: instance = self +#endregion + +#region Public Methods + + func get_speed() -> float: - if is_on_floor(): - if firing: - return FOCUS_SPEED - if Input.is_action_pressed("sprint"): - return SPRINT_SPEED - return RUN_SPEED - return AIR_SPEED + var speed := run_speed + if Input.is_action_pressed("sprint"): + speed = sprint_speed + if crouching: + speed = sneak_speed + if firing: + speed = focus_speed + if not is_on_floor(): + speed *= air_speed_factor + return speed func get_friction() -> float: if is_on_floor(): - return GROUND_FRICTION - return AIR_FRICTION + return ground_friction + return air_friction func get_tool() -> Tool: @@ -71,6 +99,34 @@ func remove_item(item: Item, amount: int = 1) -> void: inventory.erase(item) +func crouch() -> void: + if not crouching and not crouch_animation.is_playing(): + crouch_animation.play("crouch") + crouching = true + + +func uncrouch() -> void: + if ( + crouching + and not crouch_animation.is_playing() + and not crouch_head_area.has_overlapping_bodies() + ): + crouch_animation.play_backwards("crouch") + crouching = false + + +func toggle_crouch() -> void: + if crouching: + uncrouch() + else: + crouch() + + +#endregion + +#region _physics_process + + func _physics_process(delta: float) -> void: # Will be null if no valid interactor is selected. var interactive: Interactive = interact_ray.get_collider() as Interactive @@ -105,6 +161,16 @@ func _physics_process(delta: float) -> void: if Input.is_action_just_pressed("switch_mode"): get_tool().switch_mode() + # Two sneaking modes -- hold and toggle + if Game.settings.hold_to_sneak: + if Input.is_action_pressed("sneak"): + crouch() + else: + uncrouch() + else: + if Input.is_action_just_pressed("sneak"): + toggle_crouch() + # Gravity if not is_on_floor(): velocity += gravity * delta @@ -117,7 +183,7 @@ func _physics_process(delta: float) -> void: velocity.x += movement.x velocity.z += movement.z if Input.is_action_just_pressed("jump") and is_on_floor(): - velocity.y = JUMP_FORCE + velocity.y = jump_force # Friction var friction := get_friction() @@ -125,3 +191,5 @@ func _physics_process(delta: float) -> void: velocity.z = lerpf(velocity.z, 0, friction) move_and_slide() + +#endregion diff --git a/src/player/player.tscn b/src/player/player.tscn index a0bb45c..40f1521 100644 --- a/src/player/player.tscn +++ b/src/player/player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=49 format=3 uid="uid://bwe2jdmvinhqd"] +[gd_scene load_steps=56 format=3 uid="uid://bwe2jdmvinhqd"] [ext_resource type="Script" uid="uid://buwh0g1ga2aka" path="res://src/player/player.gd" id="1_npueo"] [ext_resource type="Script" uid="uid://cx1yt0drthpw3" path="res://src/player/camera_controller.gd" id="2_veeqv"] @@ -30,6 +30,7 @@ [ext_resource type="AudioStream" uid="uid://div20rlq8ync5" path="res://assets/sfx/footsteps/plastic/plastic1.wav" id="28_dpt0q"] [ext_resource type="AudioStream" uid="uid://djucfo3l7x7px" path="res://assets/sfx/footsteps/plastic/plastic3.wav" id="29_wcxbk"] [ext_resource type="AudioStream" uid="uid://ck86vhmbg3xnj" path="res://assets/sfx/footsteps/plastic/plastic5.wav" id="30_p6grl"] +[ext_resource type="Script" uid="uid://c5o1d2shq2qig" path="res://src/world/game_sound/game_sound_emitter.gd" id="31_wcxbk"] [sub_resource type="Animation" id="Animation_x42xx"] length = 0.001 @@ -151,7 +152,6 @@ animation = &"RESET" [sub_resource type="AnimationNodeTimeScale" id="AnimationNodeTimeScale_8ydov"] [sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_ylhto"] -graph_offset = Vector2(-33.7273, -38.6364) nodes/blend/node = SubResource("AnimationNodeBlend2_o822w") nodes/blend/position = Vector2(779, 166) nodes/bob_anim/node = SubResource("AnimationNodeAnimation_x42xx") @@ -171,6 +171,10 @@ node_connections = [&"blend", 0, &"still_anim", &"blend", 1, &"bob_anim", &"outp radius = 0.4 height = 1.9 +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_dpt0q"] +radius = 0.4 +height = 1.2 + [sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_8ydov"] random_pitch = 1.1 streams_count = 6 @@ -222,43 +226,244 @@ stream_0/stream = ExtResource("28_dpt0q") stream_1/stream = ExtResource("29_wcxbk") stream_2/stream = ExtResource("30_p6grl") +[sub_resource type="SphereShape3D" id="SphereShape3D_wcxbk"] +radius = 4.0 + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_wcxbk"] +radius = 0.4 +height = 1.8 + +[sub_resource type="Animation" id="Animation_dpt0q"] +resource_name = "crouch" +length = 0.2 +step = 0.01 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("CameraPosition:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(0, -0.1, 0, 0.1, 0, 0, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0, 0.2) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("CameraPosition:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(0.5, -0.1, 0, 0.1, 0, -0.2, -0.2, 0, 0.1, 0), +"times": PackedFloat32Array(0, 0.2) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("CameraPosition:position:z") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(0, -0.1, 0, 0.1, 0, 0, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0, 0.2) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("CameraPosition:rotation:x") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(0, -0.1, 0, 0.1, 0, 0, -0.1, 0, 0.1, 0, 0, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0, 0.1, 0.2) +} +tracks/4/type = "bezier" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("CameraPosition:rotation:y") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(0, -0.1, 0, 0.1, 0, 0, -0.1, 0, 0.1, 0, 0, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0, 0.1, 0.2) +} +tracks/5/type = "bezier" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("CameraPosition:rotation:z") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(0, -0.1, 0, 0.01, 0, -0.02, -0.01, 0, 0.01, 0, 0, -0.01, 0, 0.1, 0), +"times": PackedFloat32Array(0, 0.1, 0.2) +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("StandingCollider:disabled") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.01), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [false, true] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("CrouchingCollider:disabled") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0, 0.01), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, false] +} + +[sub_resource type="Animation" id="Animation_wcxbk"] +length = 0.001 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("CameraPosition:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("CameraPosition:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0.5, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("CameraPosition:position:z") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0) +} +tracks/3/type = "bezier" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("CameraPosition:rotation:x") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0) +} +tracks/4/type = "bezier" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("CameraPosition:rotation:y") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0) +} +tracks/5/type = "bezier" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("CameraPosition:rotation:z") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0) +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("StandingCollider:disabled") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath("CrouchingCollider:disabled") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_wcxbk"] +_data = { +&"RESET": SubResource("Animation_wcxbk"), +&"crouch": SubResource("Animation_dpt0q") +} + [node name="Player" type="CharacterBody3D"] -collision_layer = 9 +collision_layer = 8 script = ExtResource("1_npueo") -[node name="CameraPivot" type="Node3D" parent="."] -unique_name_in_owner = true +[node name="CameraPosition" type="Node3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) + +[node name="CameraPivot" type="Node3D" parent="CameraPosition"] +unique_name_in_owner = true script = ExtResource("2_veeqv") -[node name="ToolMount" type="Node3D" parent="CameraPivot" node_paths=PackedStringArray("initial_tool")] +[node name="ToolMount" type="Node3D" parent="CameraPosition/CameraPivot" node_paths=PackedStringArray("initial_tool")] unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.15, -0.1, -0.1) script = ExtResource("3_jiejy") initial_tool = NodePath("PointSpray") -[node name="PointSpray" parent="CameraPivot/ToolMount" instance=ExtResource("3_6wgkm")] +[node name="PointSpray" parent="CameraPosition/CameraPivot/ToolMount" instance=ExtResource("3_6wgkm")] unique_name_in_owner = true -[node name="WideSpray" parent="CameraPivot/ToolMount" instance=ExtResource("3_ibq07")] +[node name="WideSpray" parent="CameraPosition/CameraPivot/ToolMount" instance=ExtResource("3_ibq07")] unique_name_in_owner = true visible = false -[node name="Toothbrush" parent="CameraPivot/ToolMount" instance=ExtResource("6_o822w")] +[node name="Toothbrush" parent="CameraPosition/CameraPivot/ToolMount" instance=ExtResource("6_o822w")] unique_name_in_owner = true visible = false -[node name="CameraPosition" type="Node3D" parent="CameraPivot"] - -[node name="Camera3D" type="Camera3D" parent="CameraPivot/CameraPosition"] +[node name="Camera3D" type="Camera3D" parent="CameraPosition/CameraPivot"] current = true -[node name="InteractRay" type="RayCast3D" parent="CameraPivot/CameraPosition/Camera3D"] +[node name="InteractRay" type="RayCast3D" parent="CameraPosition/CameraPivot/Camera3D"] unique_name_in_owner = true target_position = Vector3(0, 0, -1.5) collision_mask = 2 -[node name="FarLight" type="OmniLight3D" parent="CameraPivot/CameraPosition/Camera3D"] +[node name="FarLight" type="OmniLight3D" parent="CameraPosition/CameraPivot/Camera3D"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.1) light_energy = 0.05 light_specular = 0.01 @@ -266,18 +471,18 @@ light_cull_mask = 4294967293 omni_range = 50.0 omni_attenuation = 0.0 -[node name="NearLight" type="OmniLight3D" parent="CameraPivot/CameraPosition/Camera3D"] +[node name="NearLight" type="OmniLight3D" parent="CameraPosition/CameraPivot/Camera3D"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.1) light_specular = 0.01 light_cull_mask = 4294967293 omni_range = 2.0 -[node name="HeadbobAnimation" type="AnimationPlayer" parent="CameraPivot/CameraPosition/Camera3D"] +[node name="HeadbobAnimation" type="AnimationPlayer" parent="CameraPosition/CameraPivot/Camera3D"] libraries = { &"": SubResource("AnimationLibrary_l271a") } -[node name="HeadbobController" type="AnimationTree" parent="CameraPivot/CameraPosition/Camera3D/HeadbobAnimation"] +[node name="HeadbobController" type="AnimationTree" parent="CameraPosition/CameraPivot/Camera3D/HeadbobAnimation"] unique_name_in_owner = true root_node = NodePath("%HeadbobController/../..") tree_root = SubResource("AnimationNodeBlendTree_ylhto") @@ -287,10 +492,15 @@ parameters/sfx_add/add_amount = 1.0 parameters/timescale/scale = false script = ExtResource("7_x42xx") -[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +[node name="StandingCollider" type="CollisionShape3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.05, 0) shape = SubResource("CapsuleShape3D_s7f0r") +[node name="CrouchingCollider" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.4, 0) +shape = SubResource("CapsuleShape3D_dpt0q") +disabled = true + [node name="PlayerHUD" parent="." instance=ExtResource("5_jvafu")] unique_name_in_owner = true @@ -343,3 +553,26 @@ bus = &"SFX" [node name="FootCast" type="RayCast3D" parent="FootstepController"] unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0518835, 0) + +[node name="FootstepGameSoundEmitter" type="Area3D" parent="FootstepController"] +unique_name_in_owner = true +collision_layer = 0 +collision_mask = 16 +script = ExtResource("31_wcxbk") +metadata/_custom_type_script = "uid://c5o1d2shq2qig" + +[node name="CollisionShape3D" type="CollisionShape3D" parent="FootstepController/FootstepGameSoundEmitter"] +shape = SubResource("SphereShape3D_wcxbk") + +[node name="CrouchHeadArea" type="Area3D" parent="."] +unique_name_in_owner = true +collision_layer = 0 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="CrouchHeadArea"] +shape = SubResource("CapsuleShape3D_wcxbk") + +[node name="CrouchAnimation" type="AnimationPlayer" parent="."] +unique_name_in_owner = true +libraries = { +&"": SubResource("AnimationLibrary_wcxbk") +} diff --git a/src/ui/menus/settings_menu/settings_menu.tscn b/src/ui/menus/settings_menu/settings_menu.tscn index 6efc560..a85e1dd 100644 --- a/src/ui/menus/settings_menu/settings_menu.tscn +++ b/src/ui/menus/settings_menu/settings_menu.tscn @@ -92,15 +92,15 @@ text = "SETTINGS_HEAD_BOB" [node name="TextCheckbox" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/HeadBob/PanelContainer/MarginContainer" index="0"] physics_interpolation_mode = 0 -[node name="CameraHeading" type="HBoxContainer" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList"] +[node name="InputHeading" type="HBoxContainer" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList"] layout_mode = 2 -[node name="Label" type="Label" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/CameraHeading"] +[node name="Label" type="Label" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/InputHeading"] layout_mode = 2 theme_type_variation = &"HeaderMedium" -text = "SETTINGS_GAME_CAMERA_HEADING" +text = "SETTINGS_GAME_INPUT_HEADING" -[node name="HSeparator" type="HSeparator" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/CameraHeading"] +[node name="HSeparator" type="HSeparator" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/InputHeading"] layout_mode = 2 size_flags_horizontal = 3 @@ -148,6 +148,16 @@ text = "SETTINGS_INVERT_PITCH" [node name="TextCheckbox" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/InvertPitch/PanelContainer/MarginContainer" index="0"] physics_interpolation_mode = 0 +[node name="HoldToSneak" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList" groups=["Settings"] instance=ExtResource("2_f274v")] +layout_mode = 2 +key = &"game/config/input/hold_to_sneak" + +[node name="SettingLabel" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/HoldToSneak" index="1"] +text = "SETTINGS_HOLD_TO_SNEAK" + +[node name="TextCheckbox" parent="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/HoldToSneak/PanelContainer/MarginContainer" index="0"] +physics_interpolation_mode = 0 + [node name="SETTINGS_GRAPHICS" type="MarginContainer" parent="TabContainer"] visible = false layout_mode = 2 @@ -332,5 +342,6 @@ text = "UI_ACCEPT" [editable path="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/SensitivityY"] [editable path="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/MouseAcceleration"] [editable path="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/InvertPitch"] +[editable path="TabContainer/SETTINGS_GAME/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/HoldToSneak"] [editable path="TabContainer/SETTINGS_GRAPHICS/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/Fullscreen"] [editable path="TabContainer/SETTINGS_GRAPHICS/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/VSync"]