Using input functions for player movement has a tiny pause.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By jujumumu

Using input events for player movement has a tiny pause when changing directions.

Previous code without pause:

 func _physics_process(delta):
    motion.y += GRAVITY*delta
    
    if Input.is_action_pressed("ui_left"):
         motion.x = -100
     elif Input.is_action_pressed("ui_right"):
         motion.x = 100
     else motion.x = 0
 
	motion = move_and_slide(motion, UP)

New code with pause:

func _unhandled_input(event):
	if event is InputEventKey:
		if event.pressed:
			if char(event.scancode) == 'A':
				motion.x=-100
			elif char(event.scancode) == 'D':
				motion.x=100
		else:
			if char(event.scancode) == 'A':
				motion.x=0
			elif char(event.scancode) == 'D':
				motion.x=0

How can I fix the pause?

:bust_in_silhouette: Reply From: Zylann

Input events is not the same thing as direct input.

In your first code, you are directly checking every frame if a button is pressed, regardless of everything else that could possibly happen.

In the second code, you are using an event handler function. _unhandled_input only receives events when they happen. It doesn’t continuously send you all the states everytime, only when they change.
Such functions are designed this way because they obey to input propagation rules, explained here: InputEvent — Godot Engine (3.1) documentation in English
The reason why it “pauses” and then “spams” is because of the standard behavior of key repetition, which simulates many press/releases, the same as when you are in a text editor and hold any key, it’s going to “spam” it after a short delay. You can also check if an event has been simulated that way by checking event.is_echo().

If you want to use _unhandled_input for realtime movement, I suggest you store states in a boolean variable which you can then check in _process. Or, since your code seems to already behave this way, don’t reset motion in _process, just apply it.

var motion = Vector2()

func _physics_process(delta):
    motion.y += GRAVITY*delta
    motion = move_and_slide(motion, UP)

func _unhandled_input(event):
    if event is InputEventKey:
        if event.pressed:
            if event.scancode == KEY_A:
                motion.x=-100
            elif event.scancode == KEY_D:
                motion.x=100
        else:
            if event.scancode == KEY_A:
                motion.x=0
            elif event.scancode == KEY_D:
                motion.x=0

Is it a good idea to use input functions or is it not. I am trying to use them because they allow input management easier. I am using what you told me but there still is a problem when changing keys there is a tiny pause because it has to first stop then go the opposite direction for a different key. Searching up tutorials does not help since most platformer tutorials do not use input functions.

jujumumu | 2019-09-10 22:59