Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

My gamepad d-pad is executing is_action_just_pressed twice #45443

Open
fagnerln opened this issue Jan 25, 2021 · 19 comments
Open

My gamepad d-pad is executing is_action_just_pressed twice #45443

fagnerln opened this issue Jan 25, 2021 · 19 comments

Comments

@fagnerln
Copy link

fagnerln commented Jan 25, 2021

Godot version:
3.2.3.stable

OS/device including version:
OpenSUSE Tumbleweed 20210120 kernel Linux 5.10.7-1

Issue description:
When I use the gamepad to control the sprite, it executes the function two times, on the keyboard and mouse button works well.

I found a similar issue here: #43492 but it's related to mouse, and my mouse is working, so maybe it's a different bug. I even set Input.set_use_accumulated_input(false) as one comment suggests, it don't work.

I created a video showing what happens:
https://www.youtube.com/watch?v=WuNF8gArbb8

Notice that the output prints the message twice when I use the gamepad

After that I discovered one more thing, it only happens on the D-Pad, I set to the analog and works correctly, and I set to the face buttons: up to Y, down to A, left to X and right to B and works well, so maybe it's a really specific bug to how it works with the D-Pad

Steps to reproduce:
1 - Open and run the project
2 - Start moving the player with the d-pad of gamepad

Minimal reproduction project:
TesteInput2.zip

It's a simple code if don't want to import the project, just put a sprite on the scene:

const TILE_SIZE = 64

func _ready():
	Input.set_use_accumulated_input(false)

func _input(event): 
	if Input.is_action_just_pressed("ui_up"):
		move_cursor(  0 , -1 )
		print(Input)
	elif Input.is_action_pressed("ui_down") and not event.is_echo():
		move_cursor(  0 ,  1 )
		print(Input)
	elif Input.is_action_just_pressed("ui_left") and event.is_pressed():
		move_cursor( -1 ,  0 )
		print(Input)
	elif Input.is_action_just_pressed("ui_right"):
		move_cursor(  1 ,  0 )
		print(Input)
		return

func move_cursor(x , y):
	$Sprite.position += Vector2(x , y) * TILE_SIZE
@Calinou
Copy link
Member

Calinou commented Jan 25, 2021

You should always use if event.is_action_pressed() instead of Input.is_action_pressed() in the _input() method. This will handle echo rejection for you automatically 🙂

@fagnerln
Copy link
Author

You should always use if event.is_action_pressed() instead of Input.is_action_pressed() in the _input() method. This will handle echo rejection for you automatically slightly_smiling_face

My intention is to use is_action_just_pressed that's why I used Input as there's no function is_action_just_pressed on event.

But I tried using if event.is_action_pressed("ui_down") and just to be sure if event.is_action_pressed("ui_down") and not event.is_echo()

My intention with this messy code is to show more techniques to move the player, and none works on the d-pad

@Calinou
Copy link
Member

Calinou commented Jan 25, 2021

My intention is to use is_action_just_pressed that's why I used Input as there's no function is_action_just_pressed on event.

event.is_action_pressed() acts just like Input.is_action_just_pressed().

@fagnerln
Copy link
Author

I thought that event.is_action_pressed() is the same as Input.is_action_pressed() and not Input.is_action_just_pressed(), it's a bit counterintuitive. Anyway, I'll try to use "event." more but the bug still happens independent of the methodology. Sorry for the off-topic.

@Calinou
Copy link
Member

Calinou commented Jan 25, 2021

Related to #21550 (but not identical judging by the description).

@p-kolacz
Copy link

I have the same problem.
Godot 3.2.3.stable, Arch Linux, Microsoft Xbox 360 Controller

Steps to reproduce:

  1. Create new project
  2. Add node and attach script:
extends Node

func _input(event):
	print(event.as_text())

Pressing and releasing D-pad in any direction shows:

InputEventJoypadButton : button_index=13, pressed=true, pressure=0
InputEventJoypadButton : button_index=13, pressed=true, pressure=0
InputEventJoypadButton : button_index=13, pressed=false, pressure=0
InputEventJoypadButton : button_index=13, pressed=false, pressure=0

while any other button works as expected:

InputEventJoypadButton : button_index=0, pressed=true, pressure=0
InputEventJoypadButton : button_index=0, pressed=false, pressure=0

@uberflut
Copy link

uberflut commented Nov 16, 2021

Same problem on godot 3.4 for windows10. It sends every Input Twice.

if Input.is_action_just_pressed("camera_right", true):
    if cardinal_count < cardinal_index.size() - 1:
        cardinal_count += 1
    else:
         cardinal_count = 0

Printing cardinal count on frame, pressing one time outputs:

0 0 0 0 1 1 2 2 2 2

Easy to fix in code with is_echo() method. (for those looking for solutions)

@snoopdouglas
Copy link
Contributor

Same problem here, also on Windows 10. My case is a Switch Pro controller connected via Steam Input

@a-wats
Copy link

a-wats commented Nov 13, 2022

I'm experiencing this bug for all button inputs using an Xbox controller on Windows 10.

@EzraT
Copy link

EzraT commented Aug 24, 2023

Still present in Godot 3.6 beta 3, using an xbox 360 controller under Fedora 38

Edit: I also tested this on Steam Deck for good measure, and the bug doesn't seem to happen on there weirdly enough, so perhaps it is an xbox controller specific issue.

Edit: With the same xbox controller connected to my Steam Deck, testing in desktop mode, the bug does occur, so this may or may not confirm its an issue specific to xbox controllers.

@Calinou
Copy link
Member

Calinou commented Aug 24, 2023

@EzraT This sounds like #76724, whose fix hasn't been cherry-picked to 3.x.

@EzraT
Copy link

EzraT commented Aug 24, 2023

@EzraT This sounds like #76724, whose fix hasn't been cherry-picked to 3.x.

Thank you. Is this going to be cherry picked for 3.6? I still use Godot 3 often so I would appreciate it.

@Calinou
Copy link
Member

Calinou commented Aug 24, 2023

Thank you. Is this going to be cherry picked for 3.6? I still use Godot 3 often so I would appreciate it.

The PR has a cherrypick:3.x label, so yes.

@Calinou
Copy link
Member

Calinou commented Feb 14, 2024

Can anyone affected by this issue test 3.6 beta4 to see if the issue is resolved there?

@EzraT
Copy link

EzraT commented Feb 14, 2024

Can anyone affected by this issue test 3.6 beta4 to see if the issue is resolved there?

Tested with an xbox 360 controller and still present in 3.6 beta4.
System info:
Fedora Linux 39 (KDE Plasma) - Wayland

@fagnerln
Copy link
Author

Can anyone affected by this issue test 3.6 beta4 to see if the issue is resolved there?

I tried and it still has the issue, I even tried Godot 4 and it has too.

Maybe its a driver bug? I've no idea who I need to report.

@Calinou
Copy link
Member

Calinou commented Feb 16, 2024

Maybe its a driver bug? I've no idea who I need to report.

If you can reproduce this in other games and applications that don't use Godot, it's a driver bug. Otherwise, it's a Godot bug.

@fagnerln
Copy link
Author

fagnerln commented Feb 16, 2024

Maybe its a driver bug? I've no idea who I need to report.

If you can reproduce this in other games and applications that don't use Godot, it's a driver bug. Otherwise, it's a Godot bug.

I never noticed double clicks in any game, and no idea how to "proof" it, so I take a look on Defold engine (I have no idea how it works) and tried to reproduce this issue, but looks like it works correctly, just printing once (not sure if it's a valid comparison).

function on_input(self, action_id, action)
	if action_id == hash("key_pressed_up") and action.pressed then
		print("Up!")
	end
	if action_id == hash("key_pressed_down") and action.pressed then
		print("Down!")
	end
	if action_id == hash("key_pressed_left") and action.pressed then
		print("Left!")
	end
	if action_id == hash("key_pressed_right") and action.pressed then
		print("Right!")
	end
end

@Rindbee
Copy link
Contributor

Rindbee commented Aug 18, 2024

Possibly related to #66878.

If it is convenient, you can use evtest/evemu-record to test the keycode mapping of the controller on Linux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants