godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.01k stars 21.17k forks source link

Input.get_vector() incorrectly uses joypad axis when using keyboard #55264

Open KoBeWi opened 2 years ago

KoBeWi commented 2 years ago

Bugsquad note: This issue has been confirmed several times already. No need to confirm it further.


Godot version

3.4 / 4.0

System information

W10

Issue description

I have movement actions mapped both to keyboard buttons and joypad analog sticks. When I press keyboard key, the Input.get_vector() will report a rotated vector, as if it was reading the joypad axis. But when I don't press anything, the vector is correctly 0.

Joypad and keyboard shouldn't interfere like this. Interestingly, the issue gets fixed after I press keys for every axis.

CC @aaronfranke

Steps to reproduce

  1. Add a set of actions using both keyboard and joypad axes
  2. Make sure you have a joypad connected
  3. Print Input.get_vector() and press the keyboard keys
  4. Notice the vector isn't aligned to axis as you'd expect

Minimal reproduction project

TestProject.zip Hold D and check the vector. You can also press WSAD and see that the vector gets fixed. (needs a connected controller)

Calinou commented 2 years ago

Related to https://github.com/godotengine/godot/issues/45628 (possible duplicate?).

aaronfranke commented 2 years ago

@KoBeWi What are the raw strength values? I suspect this is related to https://github.com/godotengine/godot-docs/issues/5378

This is starting to convince me that @golddotasksquestions was right and the circular deadzone is always worse than the cross-shaped deadzone.

KoBeWi commented 2 years ago

45628 looks like the same issue, but I can't reproduce it with the provided project. It uses Input.get_action_strenght(), which works fine for me.

KoBeWi commented 2 years ago

What are the raw strength values?

These are the values when I hold right action on keyboard:

(0.985020, -0.037025) L 0.00784301757812 R 1 U 0.03729362040758 D 0

(the first one is the vector)

Seems like both left and right are non-zero...

akien-mga commented 2 years ago

If it's a duplicate of #45628, it might be fixed by #47599. Would be worth testing to confirm.

madmiraal commented 2 years ago

If it's a duplicate of https://github.com/godotengine/godot/issues/45628, it might be fixed by https://github.com/godotengine/godot/pull/47599. Would be worth testing to confirm.

This issue is more than #45628. Although things would be improved by #47599, this is primarily an issue with dead zones as discussed in godotengine/godot-proposals#3709. Specifically, should joysticks have a circular dead zone (as suggested by https://github.com/godotengine/godot/pull/42976#issuecomment-714419377), a cross-shaped dead zone (as suggested by this issue), or should the user be able to decide.

jojorne commented 3 months ago

Unless I'm misunderstanding, this seems like the same issue as #90515?

ygypt commented 3 months ago

This is essential for any game, and its astonishing that this issues been open for as long as it has. Could this be fixed with a few lines? If one device is within deadzone, don't apply it's strength to the vector

jojorne commented 3 months ago

The workaround works. You need to split the devices on their own entry and check the input with methods that accept names, e g., "left_kb" || "left_js".