From f77d98bd39376ae42092718aa0603e5cfa6e2fcf Mon Sep 17 00:00:00 2001 From: ninetailsrabbit Date: Wed, 30 Oct 2024 14:08:48 +0000 Subject: [PATCH] changed InputControls strings to StringName and implemented drag drop sistem for 2D and 3D --- autoload/general/global_day_night_clock.gd | 2 +- .../persistence/settings/input_controls.gd | 55 +++++---- components/drag_drop/2D/draggable_2d.svg | 8 ++ .../drag_drop/2D/draggable_2d.svg.import | 37 ++++++ .../drag_drop/2D/draggable_sprite_2d.gd | 105 ++++++++++++++++++ components/drag_drop/3D/drag_and_drop_3d.gd | 79 +++++++++++++ components/drag_drop/3D/drag_drop_3d.svg | 7 ++ .../drag_drop/3D/drag_drop_3d.svg.import | 37 ++++++ components/drag_drop/3D/draggable_3d.gd | 63 +++++++++++ components/drag_drop/3D/draggable_3d.svg | 8 ++ .../drag_drop/3D/draggable_3d.svg.import | 37 ++++++ .../interaction/3D/grabbables/grabber_3d.gd | 10 +- .../mouse_raycast_interactor_3d.gd | 2 +- .../3D/interactors/raycast_interactor_3d.gd | 4 +- .../controller/states/ground/ground.gd | 12 +- .../firearm_weapon_motion_configuration.gd | 2 +- project.godot | 2 +- ui/performance/metrics/performance_metrics.gd | 2 +- utilities/input/transformed_input.gd | 16 +-- 19 files changed, 438 insertions(+), 50 deletions(-) create mode 100644 components/drag_drop/2D/draggable_2d.svg create mode 100644 components/drag_drop/2D/draggable_2d.svg.import create mode 100644 components/drag_drop/2D/draggable_sprite_2d.gd create mode 100644 components/drag_drop/3D/drag_and_drop_3d.gd create mode 100644 components/drag_drop/3D/drag_drop_3d.svg create mode 100644 components/drag_drop/3D/drag_drop_3d.svg.import create mode 100644 components/drag_drop/3D/draggable_3d.gd create mode 100644 components/drag_drop/3D/draggable_3d.svg create mode 100644 components/drag_drop/3D/draggable_3d.svg.import diff --git a/autoload/general/global_day_night_clock.gd b/autoload/general/global_day_night_clock.gd index 6ad5b45..a029129 100644 --- a/autoload/general/global_day_night_clock.gd +++ b/autoload/general/global_day_night_clock.gd @@ -5,7 +5,7 @@ signal time_tick(day: int, hour: int, minute: int) const MinutesPerDay: int = 1440 const MinutesPerHour: int = 60 -const InGameToRealMinuteDuration: int = TAU / MinutesPerDay +const InGameToRealMinuteDuration := TAU / MinutesPerDay ## This value when it's 1.0 means that one minute in real time translates into one second in-game, so modify this value as is needed @export var in_game_speed: float = 1.0 diff --git a/autoload/persistence/settings/input_controls.gd b/autoload/persistence/settings/input_controls.gd index 6958fd8..e0b0b50 100644 --- a/autoload/persistence/settings/input_controls.gd +++ b/autoload/persistence/settings/input_controls.gd @@ -1,26 +1,33 @@ class_name InputControls -const MoveRight: String = "move_right" -const MoveLeft: String = "move_left" -const MoveForward: String = "move_forward" -const MoveBack: String = "move_back" - -const Interact: String = "interact" -const CancelInteraction: String = "cancel_interact" - -const Pull: String = "pull" -const PullArea: String = "pull_area" -const Drop: String = "drop" -const Throw: String = "throw" -const PushWave: String = "push_wave" - -const Aim: String = "aim" -const Shoot: String = "shoot" - -const PrimaryWeapon: String = "primary_weapon" -const SecondaryWeapon: String = "secondary_weapon" -const HeavyWeapon: String = "heavy_weapon" -const MeleeWeapon: String = "melee_weapon" - -const PerformanceMetrics: String = "performance_metrics" -const PauseGame: String = "pause" +const MoveRight: StringName = &"move_right" +const MoveLeft: StringName = &"move_left" +const MoveForward: StringName = &"move_forward" +const MoveBack: StringName = &"move_back" + +const CrouchAction: StringName = &"crouch" +const CrawlAction: StringName = &"crawl" +const RunAction: StringName = &"run" +const JumpAction: StringName = &"jump" + +const Interact: StringName = &"interact" +const CancelInteraction: StringName = &"cancel_interact" + +const Pull: StringName = &"pull" +const PullArea: StringName = &"pull_area" +const Drop: StringName = &"drop" +const Throw: StringName = &"throw" +const PushWave: StringName = &"push_wave" + +const Aim: StringName = &"aim" +const Shoot: StringName = &"shoot" + +const PrimaryWeapon: StringName = &"primary_weapon" +const SecondaryWeapon: StringName = &"secondary_weapon" +const HeavyWeapon: StringName = &"heavy_weapon" +const MeleeWeapon: StringName = &"melee_weapon" + +const Drag: StringName = &"drag" + +const PerformanceMetrics: StringName = &"performance_metrics" +const PauseGame: StringName = &"pause" diff --git a/components/drag_drop/2D/draggable_2d.svg b/components/drag_drop/2D/draggable_2d.svg new file mode 100644 index 0000000..4d19691 --- /dev/null +++ b/components/drag_drop/2D/draggable_2d.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/components/drag_drop/2D/draggable_2d.svg.import b/components/drag_drop/2D/draggable_2d.svg.import new file mode 100644 index 0000000..42185b0 --- /dev/null +++ b/components/drag_drop/2D/draggable_2d.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dwj1m1bssf43v" +path="res://.godot/imported/draggable_2d.svg-58c1b693d1f6c4fd4492ed8cf0516dbf.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://components/drag_drop/2D/draggable_2d.svg" +dest_files=["res://.godot/imported/draggable_2d.svg-58c1b693d1f6c4fd4492ed8cf0516dbf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/components/drag_drop/2D/draggable_sprite_2d.gd b/components/drag_drop/2D/draggable_sprite_2d.gd new file mode 100644 index 0000000..5e69f4c --- /dev/null +++ b/components/drag_drop/2D/draggable_sprite_2d.gd @@ -0,0 +1,105 @@ +@icon("res://components/drag_drop/2D/draggable_2d.svg") +class_name DraggableSprite2D extends Sprite2D + +signal drag_started +signal drag_ended +signal drag_enabled +signal drag_disabled +signal mouse_released +signal picked_up_changed(picked: bool) + + +@export var reset_position_on_release: bool = true +@export var one_click_drag: bool = false +@export var smooth_factor: float = 20.0 +@export var drag_input_action: StringName = InputControls.Drag: + set(value): + drag_input_action = value + + set_process(InputMap.has_action(drag_input_action)) + +var mouse_region: Button +var current_position: Vector2 = Vector2.ZERO +var m_offset: Vector2 = Vector2.ZERO + +var original_global_position: Vector2 = Vector2.ZERO +var original_position: Vector2 = Vector2.ZERO + +var drag_active: bool = false: + set(value): + if drag_active != value: + drag_active = value + + if drag_active: + drag_enabled.emit() + else: + drag_disabled.emit() + + +var picked_up: bool = false: + set(value): + if picked_up != value: + picked_up = value + + picked_up_changed.emit(picked_up) + + if picked_up: + drag_started.emit() + else: + drag_ended.emit() + reset_position() + + +func _ready() -> void: + original_global_position = global_position + original_position = position + + if mouse_region == null: + mouse_region = Button.new() + mouse_region.self_modulate.a8 = 0 + add_child(mouse_region) + + + resize_mouse_region() + mouse_region.button_down.connect(on_mouse_region_pressed) + mouse_released.connect(on_mouse_released) + texture_changed.connect(on_texture_changed) + + set_process(InputMap.has_action(drag_input_action)) + + +func _process(delta: float) -> void: + if InputMap.has_action(drag_input_action) and Input.is_action_just_released(drag_input_action) and picked_up: + mouse_released.emit() + + elif mouse_region.button_pressed: + global_position = global_position.lerp(get_global_mouse_position(), smooth_factor * delta) if smooth_factor > 0 else get_global_mouse_position() + current_position = global_position + m_offset + + +func reset_position() -> void: + if is_inside_tree() and reset_position_on_release: + global_position = original_global_position + position = original_position + + +func resize_mouse_region() -> void: + if mouse_region: + mouse_region.position = Vector2.ZERO + mouse_region.anchors_preset = Control.PRESET_FULL_RECT + + +func on_mouse_region_pressed() -> void: + picked_up = true + + if is_inside_tree(): + m_offset = transform.origin - get_global_mouse_position() + + +func on_mouse_released() -> void: + picked_up = false + + +func on_texture_changed() -> void: + if texture: + resize_mouse_region() diff --git a/components/drag_drop/3D/drag_and_drop_3d.gd b/components/drag_drop/3D/drag_and_drop_3d.gd new file mode 100644 index 0000000..9f2af04 --- /dev/null +++ b/components/drag_drop/3D/drag_and_drop_3d.gd @@ -0,0 +1,79 @@ +@icon("res://components/drag_drop/3D/drag_drop_3d.svg") +class_name DragAndDrop3D extends Node3D + + +@export var origin_camera: Camera3D +@export var drag_distance_from_camera: float = 20.0 + +var current_draggable: Draggable3D: + set(value): + if value != current_draggable: + current_draggable = value + + set_process_unhandled_input(current_draggable is Draggable3D) + + +func _unhandled_input(event: InputEvent) -> void: + if InputHelper.is_mouse_visible() and event is InputEventMouseMotion and current_draggable: + handle_drag_motion() + + +func _ready() -> void: + await get_tree().current_scene.ready + + for draggable: Draggable3D in get_tree().get_nodes_in_group(Draggable3D.GroupName): + draggable.drag_started.connect(on_draggable_drag_started.bind(draggable)) + draggable.drag_ended.connect(on_draggable_drag_ended.bind(draggable)) + + get_tree().root.child_entered_tree.connect(on_child_entered_tree) + get_tree().root.child_exiting_tree.connect(on_child_exiting_tree) + + +func handle_drag_motion(): + if origin_camera and current_draggable: + var mouse_position: Vector2 = get_viewport().get_mouse_position() + + var world_space := get_world_3d().direct_space_state + var from := origin_camera.project_ray_origin(mouse_position) + var to := origin_camera.project_position(mouse_position, drag_distance_from_camera) + + var ray_query = PhysicsRayQueryParameters3D.create( + from, + to, + ) + + ray_query.exclude = [current_draggable.get_rid()] + + ray_query.collide_with_areas = false + ray_query.collide_with_bodies = true + + var result := world_space.intersect_ray(ray_query) + + if result.has("position"): + current_draggable.target.global_position = result.position + + +#region Signal callbacks +func on_draggable_drag_started(draggable: Draggable3D) -> void: + current_draggable = draggable + + +func on_draggable_drag_ended(draggable: Draggable3D) -> void: + current_draggable = null + + +func on_child_entered_tree(child: Node) -> void: + if child is Draggable3D: + child.drag_started.connect(on_draggable_drag_started.bind(child)) + child.drag_ended.connect(on_draggable_drag_ended.bind(child)) + + +func on_child_exiting_tree(child: Node) -> void: + if child is Draggable3D: + if child.drag_started.is_connected(on_draggable_drag_started): + child.drag_started.disconnect(on_draggable_drag_started) + + if child.drag_ended.is_connected(on_draggable_drag_started): + child.drag_ended.disconnect(on_draggable_drag_ended) + +#endregion diff --git a/components/drag_drop/3D/drag_drop_3d.svg b/components/drag_drop/3D/drag_drop_3d.svg new file mode 100644 index 0000000..eae163d --- /dev/null +++ b/components/drag_drop/3D/drag_drop_3d.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/components/drag_drop/3D/drag_drop_3d.svg.import b/components/drag_drop/3D/drag_drop_3d.svg.import new file mode 100644 index 0000000..653f14f --- /dev/null +++ b/components/drag_drop/3D/drag_drop_3d.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://djue3vbtyuq73" +path="res://.godot/imported/drag_drop_3d.svg-8f3ab5ff1ea8f347f604b93391d16b3c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://components/drag_drop/3D/drag_drop_3d.svg" +dest_files=["res://.godot/imported/drag_drop_3d.svg-8f3ab5ff1ea8f347f604b93391d16b3c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/components/drag_drop/3D/draggable_3d.gd b/components/drag_drop/3D/draggable_3d.gd new file mode 100644 index 0000000..788eede --- /dev/null +++ b/components/drag_drop/3D/draggable_3d.gd @@ -0,0 +1,63 @@ +@icon("res://components/drag_drop/3D/draggable_3d.svg") +class_name Draggable3D extends Node3D + +signal drag_started +signal drag_ended + +const GroupName: StringName = &"draggable" + +## It only supports nodes that inherits from CollisionObject3D (Area3D, and PhysicsBody3D related) +@export var target: CollisionObject3D: + set(value): + if value != target: + + if is_inside_tree() and value == null and target is CollisionObject3D: + if target.input_event.is_connected(on_target_input_event): + target.input_event.disconnect(on_target_input_event) + + is_dragging = false + + target = value + + if target is CollisionObject3D and is_inside_tree(): + original_position = target.global_position + + if not target.input_event.is_connected(on_target_input_event): + target.input_event.connect(on_target_input_event) + +@export var reset_position_on_release: bool = false + +var original_position: Vector3 + +var is_dragging: bool = false: + set(value): + if is_dragging != value: + is_dragging = value + + if is_dragging: + drag_started.emit() + else: + drag_ended.emit() + + if reset_position_on_release: + target.global_position = original_position + + +func _enter_tree() -> void: + add_to_group(GroupName) + + if target: + target.input_event.connect(on_target_input_event) + original_position = target.global_position + + +func get_rid() -> RID: + return target.get_rid() + + +func on_target_input_event(_camera: Node, event: InputEvent, _event_position: Vector3, _normal: Vector3, _shape_idx: int) -> void: + if InputHelper.is_mouse_visible(): + event = InputHelper.double_click_to_single(event) + is_dragging = InputHelper.is_mouse_left_button_pressed(event) + + diff --git a/components/drag_drop/3D/draggable_3d.svg b/components/drag_drop/3D/draggable_3d.svg new file mode 100644 index 0000000..a94cadc --- /dev/null +++ b/components/drag_drop/3D/draggable_3d.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/components/drag_drop/3D/draggable_3d.svg.import b/components/drag_drop/3D/draggable_3d.svg.import new file mode 100644 index 0000000..9914343 --- /dev/null +++ b/components/drag_drop/3D/draggable_3d.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dbwqfv3nv61t1" +path="res://.godot/imported/draggable_3d.svg-db48fd0a441643dd357f4baaf4ee5f45.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://components/drag_drop/3D/draggable_3d.svg" +dest_files=["res://.godot/imported/draggable_3d.svg-db48fd0a441643dd357f4baaf4ee5f45.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/components/interaction/3D/grabbables/grabber_3d.gd b/components/interaction/3D/grabbables/grabber_3d.gd index 2de0c79..c06f315 100644 --- a/components/interaction/3D/grabbables/grabber_3d.gd +++ b/components/interaction/3D/grabbables/grabber_3d.gd @@ -21,11 +21,11 @@ signal dropped_grabbable(body: Grabbable3D) ## The maximum number of grabbables this grabber can hold at the same time, this takes priority over available_slots @export var max_number_of_grabbables: int = 1 @export_group("Input Actions") -@export var pull_input_action: String = InputControls.Pull -@export var pull_area_input_action: String = InputControls.PullArea -@export var drop_input_action: String = InputControls.Drop -@export var throw_input_action: String = InputControls.Throw -@export var push_wave_input_action: String = InputControls.PushWave +@export var pull_input_action: StringName = InputControls.Pull +@export var pull_area_input_action: StringName = InputControls.PullArea +@export var drop_input_action: StringName = InputControls.Drop +@export var throw_input_action: StringName = InputControls.Throw +@export var push_wave_input_action: StringName = InputControls.PushWave @export_group("Abilities") @export var pull_individual_ability: bool = true @export var pull_area_ability: bool = false diff --git a/components/interaction/3D/interactors/mouse_raycast_interactor_3d.gd b/components/interaction/3D/interactors/mouse_raycast_interactor_3d.gd index ae2bc6e..5ac97a1 100644 --- a/components/interaction/3D/interactors/mouse_raycast_interactor_3d.gd +++ b/components/interaction/3D/interactors/mouse_raycast_interactor_3d.gd @@ -3,7 +3,7 @@ class_name MouseRayCastInteractor3D extends Node3D @export var origin_camera: Camera3D @export var ray_length: float = 1000.0 @export var interact_mouse_button = MOUSE_BUTTON_LEFT -@export var cancel_interact_input_action: String = InputControls.CancelInteraction +@export var cancel_interact_input_action: StringName = InputControls.CancelInteraction @onready var current_camera: Camera3D = origin_camera: set(new_camera): diff --git a/components/interaction/3D/interactors/raycast_interactor_3d.gd b/components/interaction/3D/interactors/raycast_interactor_3d.gd index 70e669a..b6c7cea 100644 --- a/components/interaction/3D/interactors/raycast_interactor_3d.gd +++ b/components/interaction/3D/interactors/raycast_interactor_3d.gd @@ -1,7 +1,7 @@ class_name RayCastInteractor3D extends RayCast3D -@export var interact_input_action: String = InputControls.Interact -@export var cancel_interact_input_action: String = InputControls.CancelInteraction +@export var interact_input_action: StringName = InputControls.Interact +@export var cancel_interact_input_action: StringName = InputControls.CancelInteraction var current_interactable: Interactable3D diff --git a/components/motion/3D/first-person/controller/states/ground/ground.gd b/components/motion/3D/first-person/controller/states/ground/ground.gd index b74c9e1..00bb187 100644 --- a/components/motion/3D/first-person/controller/states/ground/ground.gd +++ b/components/motion/3D/first-person/controller/states/ground/ground.gd @@ -19,13 +19,13 @@ class_name GroundState extends MachineState ## Shortcut for converting vectors to horizontal @export var horizontal := Vector3(1, 0, 1) @export_group("Input actions") -@export var run_input_action: String = "run" -@export var jump_input_action: String = "jump" -@export var crouch_input_action: String = "crouch" -@export var crawl_input_action: String = "crawl" +@export var run_input_action: StringName = InputControls.RunAction +@export var jump_input_action: StringName = InputControls.JumpAction +@export var crouch_input_action: StringName = InputControls.CrouchAction +@export var crawl_input_action: StringName = InputControls.CrawlAction @export_group("Animation") -@export var crouch_animation: String = "crouch" -@export var crawl_animation: String = "crawl" +@export var crouch_animation: StringName = "crouch" +@export var crawl_animation: StringName = "crawl" var current_speed: float = 0 var stair_stepping := false diff --git a/components/motion/3D/first-person/shooter/weapons/configuration/firearm_weapon_motion_configuration.gd b/components/motion/3D/first-person/shooter/weapons/configuration/firearm_weapon_motion_configuration.gd index 44eb531..138548b 100644 --- a/components/motion/3D/first-person/shooter/weapons/configuration/firearm_weapon_motion_configuration.gd +++ b/components/motion/3D/first-person/shooter/weapons/configuration/firearm_weapon_motion_configuration.gd @@ -9,7 +9,7 @@ class_name FireArmWeaponMotionConfiguration extends Resource @export var camera_recoil_enabled: bool = true @export var camera_shake_enabled: bool = true @export_group("Aim") -@export var aim_input_action: String = InputControls.Aim +@export var aim_input_action: StringName = InputControls.Aim @export var keep_pressed_to_aim: bool = true @export var center_weapon_on_aim: bool = true @export_group("Camera shake") diff --git a/project.godot b/project.godot index d0952c0..f87d7a0 100644 --- a/project.godot +++ b/project.godot @@ -12,7 +12,7 @@ config_version=5 config/name="IndieBlueprint" config/description="is a comprehensive Godot project template designed to streamline your development process. It includes essential features, optimized settings, and best practices to help you create amazing indie game" -config/version="1.0.8" +config/version="1.1.1" run/main_scene="res://scenes/entry_point/game-entry_point.tscn" config/features=PackedStringArray("4.3", "Forward Plus") config/icon="res://icon.svg" diff --git a/ui/performance/metrics/performance_metrics.gd b/ui/performance/metrics/performance_metrics.gd index 3e4a297..2a136a5 100644 --- a/ui/performance/metrics/performance_metrics.gd +++ b/ui/performance/metrics/performance_metrics.gd @@ -1,7 +1,7 @@ @icon("res://ui/performance/metrics/performance_metrics.svg") extends Control -@export var show_hardware_specs_input_action: String = InputControls.PerformanceMetrics +@export var show_hardware_specs_input_action: StringName = InputControls.PerformanceMetrics @export var only_fps_counter: bool = false @onready var fps_label: Label = %FPSLabel diff --git a/utilities/input/transformed_input.gd b/utilities/input/transformed_input.gd index 4bafc59..55fd2dc 100644 --- a/utilities/input/transformed_input.gd +++ b/utilities/input/transformed_input.gd @@ -1,9 +1,9 @@ class_name TransformedInput -var move_right_action: String = InputControls.MoveRight -var move_left_action: String = InputControls.MoveLeft -var move_forward_action: String = InputControls.MoveForward -var move_back_action: String = InputControls.MoveBack +var move_right_action: StringName = InputControls.MoveRight +var move_left_action: StringName = InputControls.MoveLeft +var move_forward_action: StringName = InputControls.MoveForward +var move_back_action: StringName = InputControls.MoveBack var actor: Node var deadzone: float = 0.5: @@ -123,25 +123,25 @@ func _update_previous_directions(): #region Action setters -func change_move_right_action(new_action: String) -> TransformedInput: +func change_move_right_action(new_action: StringName) -> TransformedInput: move_right_action = new_action return self -func change_move_left_action(new_action: String) -> TransformedInput: +func change_move_left_action(new_action: StringName) -> TransformedInput: move_left_action = new_action return self -func change_move_forward_action(new_action: String) -> TransformedInput: +func change_move_forward_action(new_action: StringName) -> TransformedInput: move_forward_action = new_action return self -func change_move_back_action(new_action: String) -> TransformedInput: +func change_move_back_action(new_action: StringName) -> TransformedInput: move_back_action = new_action return self