Godot Joystick axis never rests at 0

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By genfy
:warning: Old Version Published before Godot 3 was released.

The value of joystick axis is never 0, I want the player not to move when I’m not moving the joystick.

I’ve tried using:

Input.get_joy_axis(0, 0)

and:

func _input(ev):
	if ev.type == InputEvent.JOYSTICK_MOTION:
		
		if ev.axis == 0:
			left_joy_angle.x = ev.value
		elif ev.axis == 1:
			left_joy_angle.y = ev.value
		elif ev.axis == 2:
			right_joy_angle.x = ev.value
		elif ev.axis == 3:
			right_joy_angle.y = ev.value

For the latter, the godot documentation states:

float value - Position of the axis, ranging from -1.0 to 1.0. A value of 0 means that the axis is in its neutral position.

This doesn’t happen. I don’t know if I’m doing something wrong, or maybe it’s a bug.

Here is a good article on this.

D | 2016-12-07 21:23

:bust_in_silhouette: Reply From: Hinsbart

You’re neither doing something wrong, nor is it a bug.
Gamepad joysticks are often not centered 100% and also wear down and loose precision over time, so this is a hardware problem. So far I’ve tested like 8 different controllers and only one or two actually reset to a perfect 0.0 value.
Maybe the documentation could be improved a little in this regard… something like “a value approaching zero means the axis is in neutral position”
The best practise here is to have some kind of deadzone handling in your gameplay code.
The reason godot doesn’t handle gamepad deadzones internally, is that there’s many different ways of achieving this. You could have a circular-deadzone, a square one, an axis-independent one, etc… Each having a different kind of effect on the “feel” of your gameplay, so it’s up to the user to decide on how to apply the deadzone.

:bust_in_silhouette: Reply From: rgrams

Not a bug or you doing anything wrong; it’s because there’s no deadzone, and it depends on your joystick. A gamepad, depending on which one you have and how used it is, may be pretty bad at springing back to (0, 0), especially if you release it from full extension.

It’s pretty easy to code in a deadzone yourself though. There are multiple ways, here’s one:

var deadzone = 0.25

func _input(ev):
    if ev.type == InputEvent.JOYSTICK_MOTION:
        if ev.axis == 0:
            left_joy_angle.x = ev.value
        elif ev.axis == 1:
            left_joy_angle.y = ev.value

    if left_joy_angle.length() <= deadzone:
        left_joy_angle = Vector2(0, 0)