Joystick analog stick reads a 0 at extremes

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

I’m beginning to make a game and decided to use an input map to better support remapping and controller. Here’s the issue, when I use the analog stick vertical axis for “movement_up” and “movement_down” it reads out as a 0 at the extremes. So if you are halfway between the bottom and the middle, event.get_action_strength(“movement_down”) returns ~0.5 as it should. However if it is all the way at the bottom, instead of a 1 it returns a 0. This means that the player will stop moving if the analog stick is at any extreme, when in reality it should be moving at its fastest. Windows reads the gamepad successfully, and I’ve tried this with two different gamepads, getting the same result. (I’m on 3.2.3 stable if that helps pinpoint a patched bug or something)

EDIT:
I’ve done some more testing, and have some more to report. The issue also occurs on both a Switch Pro controller and a Xbox Wireless Controller, either wired or wireless. I don’t have any PS4 controllers but from what I’ve gathered so far it would be the same. Curiously, the switch pro controller seems to have a range of 0-0.7, before zeroing out at the extreme, while the xbox controller has a range of 0-0.9, zeroing out at the extreme. Windows itself still reports the joysticks as functioning properly (can get the full range in the built-in tester). With this happening on three controllers from two different manufacturers I can confirm that this is some sort of engine issue.

Attached here is a video that should document the issue:

You are using event.get_action_strength, so i guess, you are reading this in _input?
can your post the whole _input method?

I also think its better is you use Input.get_action_strength in _process or _physics_process

whiteshampoo | 2021-03-11 15:03

func _input(event):
if event is InputEventMouseMotion and cap:
	curMovement = Vector2(0,event.relative.y*sensitivity)
	mouse = true
else:
	if event.is_action_pressed("pause"):
		if cap:
			cap = false
			Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
		else:
			cap = true
			Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	elif event.is_action_pressed("movement_up") or event.is_action_pressed("movement_down"):
		mouse = false
curAxis = Vector2(0,event.get_action_strength("movement_down")-event.get_action_strength("movement_up"))

this is my input function. Get action strength returns the same if it is used in process or physics process, which is the strange analog stick behavior

coppyhop | 2021-03-11 16:40

I am running Godot 3.4.4 stable with an XBox Controller on a PC. I can confirm the same. When a stick is fully pushed left or right: get_action_strength for that axis returns 0. Expected: it should return 1.0

I was able to get around this by using Input.get_action_raw_strength and implementing my own deadzone handling.

jeff-kwak | 2022-08-04 08:45