InputMap additions using GDScript

Godot Version

4.4.1

Question

I am trying to create a base template for a 2d rpg game.
I want to bet the tool script that configures various things in the engine to add and update actions in the project/inputmap.
I have created an initial_setup.gd script with various settings that get set when it is run, but when I try to get it to add actions to the InputMap they are not persistent.
Here is the script I am running.

@tool extends EditorScript

func _run() → void:
ProjectSettings.set(“display/window/size/viewport_width”, 320)
ProjectSettings.set(“display/window/size/viewport_height”, 180)
ProjectSettings.set(“display/window/size/viewport_width_override”, 1280)
ProjectSettings.set(“display/window/size/viewport_height_override”, 720)
ProjectSettings.set(“display/window/stretch/mode”, “viewport”)
ProjectSettings.set(“rendering/textures/canvas_textures/default_texture_filter”, “Nearest”)
ProjectSettings.set(“application/config/version”, “0.0.1”)
ProjectSettings.set(“application/config/use_custom_user_dir”, true)
ProjectSettings.set(“rendering/2d/snap/snap_2d_transforms_to_pixel”, true)
ProjectSettings.set(“rendering/2d/snap/snap_2d_vertices_to_pixel”, true)
var action_name := “attack”
# Create an input event for the ESC key
var esc_event := InputEventKey.new()
esc_event.physical_keycode = KEY_ESCAPE

# Add the action if it doesn't exist
if not InputMap.has_action(action_name):
	InputMap.add_action(action_name)

# Check if the ESC key is already bound to avoid duplicates
var already_added := false
for event in InputMap.action_get_events(action_name):
	if event is InputEventKey and event.physical_keycode == KEY_ESCAPE:
		already_added = true
		break

if not already_added:
	InputMap.action_add_event(action_name, esc_event)
    ## This outputs a display of the InputMap
for action: String in InputMap.get_actions():
	for event: InputEvent in InputMap.action_get_events(action):
		var action_and_event_text: String = "%s | %s" % [action, event.as_text()]
		print(action_and_event_text)

ProjectSettings.save()

When I run the script it shows that the action “attack” has been added to the InputMap as the last item in the list.
The problem I have is that when the project is reloaded the action is no longer there unless the script is run again. Does anyone know of a way to get this to work.

As an aside, I added a “ui_attack” action through the project settings dialog it does not show in the list when this script is run but it is still in the project settings list.

Thanks.

Geoff.

The InputMap and ProjectSettings are not connected. When running the script in the editor (a @tool script) the InputMap will be the one from the editor not the game. You’ll need to Object.get() and Object.set() them manually in ProjectSettings using the format input/<action_name> as the property key and with value: {"deadzone": <deadzone>, events: [<input_event>,...]}

Example:

@tool
extends EditorScript


func _run() -> void:
	var ev = InputEventMouseButton.new()
	ev.button_index = MOUSE_BUTTON_LEFT

	var action = ProjectSettings.get("input/click")
	if not action:
		action = {
			deadzone = 0.5,
			events = [ev]
		}
	else:
		# TODO check that the event isn't already added
		action.events.append(ev)

	ProjectSettings.set("input/click", action)

	ProjectSettings.save()

You may need to reload the project to see the new input map in the project settings dialog. I’m not sure if there’s a way to reload it in code.

1 Like

Thanks for that, it sort of worked, I found that the info is saved into the project.godot file, and although it saved to that file it saved to the incorrect section, but this is a start, I will keep working on it and update it when I have completed the answer,

Thanks.

I found my problem, typing error, it now works correctly, thanks for your help.