Repeat delay with _unhandled_key_input, _unhandled_input and _input

Godot Version

4.3

Question

Hi everyone.
So I’m having issues with the built in input methods _input, _unhandled_input, and _unhandled_key_input.

The issue is the classic key repeat delay when you hold a key (like you’d experiment on any text editor). It goes something like this:

KEY
nothing
nothing
nothing
KEY
KEY
KEY
KEY
KEY

Unfortunately I need to move a character, so that repeat delay is a problem. So here are some points to consider:

  1. I’ve tried with all three input methods mentioned above and they all have the same issue.

  2. There is no flag I can check for the event parameter (like is_pressed or is_echo) since the method is directly not being called. As you can see in the video below, it doesn’t even execute the print statement, for those few milliseconds the method is not being called.

  3. I’ve checked several topics and they mostly say “just use _process with is_action_pressed”. I prefer to have all those inputs inside _unhandled_key_input because I need the input to be checked after all the UI menus, otherwise they might interfere depending on the user key mapping settings

  4. Sure, it can be fixed from windows reducing that repeat delay, but as you might have guessed I can’t expect everyone who installs my game to change their accessibility settings.

  5. What I can’t find, and this is how maybe you guys can help me, is to find a way, a project setting or maybe another input method that allows me to capture fluid key input so the character moves when the key is down and stops moving when the key is up. But again, I prefer to handle it on some “unhandled_input” event, not in the _process with is_action_pressed (though of course I’ll do it if I have no other option).

Any ideas? Thanks in advance! Here’s a video example of the problem.

Sorry if this is a bit of a basic answer, but in my game I listen for the key press and then the key released. On key press I set a flag to, say, move forward. While that flag is true the character moves forward. On key released, the flag is set to false. Something like this:

	if event.is_action_pressed("Left"):
		set_ship_moving_left(true)
	elif event.is_action_released("Left"):
		set_ship_moving_left(false)

You can do this in unhandled input or just _input. Would this not solve your problem? Again if I have missed the point here apologies in advance.

Thanks, but that won’t solve the problem because as I said in #2, the methods are not being called. So even if I check the input there, they will not register for that period of time. I will have the same issue than the one I have in the video.

As an alternative you could do something along the following idea:

var calla: Callable = Callable(self, "_on_down")


func _unhandled_key_input(event: InputEvent) -> void:
	if event.is_pressed():
		print("down")
		if !get_tree().process_frame.is_connected(calla):
			get_tree().process_frame.connect(calla)
	else:
		if get_tree().process_frame.is_connected(calla):
			get_tree().process_frame.disconnect(calla)
		print("up")


func _on_down():
	print("pressed")

Yep, I’ve ended up solving it with something similar, like registering when it starts and when it ends and assuming the rest of the time the key is getting held.
It’s not perfect, but it was the best I could find.
thanks!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.