How is the Deadzone from Input Map supposed to work?

Godot Version

4.2.2

Question

I’m trying to utilize the deadzone feature from Godot’s Input Map but the vector is still receiving values below the deadzone value when using Input.get_vector on the actions that I created, even if I override the deadzone with the 5th parameter.

It’s also interfering with keyboard input since it’s mapped to the same action and causing the vectors to be inconsistent because of the analog’s drifting with no deadzone.

# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
  var input_dir = Input.get_vector("Left", "Right", "Forward", "Back", 0.5)
  var direction = Vector3(input_dir.x, 0, input_dir.y).rotated(Vector3.UP, $Camera_Controller.rotation.y).normalized()

    if direction:
        velocity.x = direction.x * SPEED
        velocity.z = direction.z * SPEED
    else: #To stop the player from moving when releasing a direction
	velocity.x = move_toward(velocity.x, 0, SPEED)
	velocity.z = move_toward(velocity.z, 0, SPEED)

This is part of the movement’s script, mostly based on the convenient script that comes with CharacterBody3D and that’s why I wanted to keep using Input.get_vector, but what is the purpose of the 5th parameter for deadzone if it’s still receiving values below it?

Are you using a controller with stick drift? If so you could run Input.get_action_strength() on the input you want and see if your controller is outputting a value greater than .5 then try adjusting the deadline to a value a little greater than that number.

I hope this helps you a good but, also, could you please explain that last question a little more, I think I know what your asking but would like to be sure.

1 Like

Think of the deadzone pushing the minimum outwards, at 0.5 you have to move the stick half way to get a 0 input out of it, then three fourths to get a 0.5 input out of it

Sounds like you have pretty bad stick drift

Yeah the stick is drifting but not that much to output a value greater than half the stick (0.5), it’s probably less than 0.1

My question was: When does the deadzone value gets used? Because putting in Input Map and in Input.get_vector as the 5th parameter is still outputting me values on the axis below the deadzone so I don’t know when it is used, look at this code that I run with Input.get_action_strength():

if Input.is_action_pressed("Left"):
		print(Input.get_action_strength("Left"))

The action “Left” has a deadzone of 0.1 but I’m still getting values below that when printing (0.04449462890625 for example)
Also notice how it’s not Input.get_action_raw_strength() which is the one that should ignore deadzone

It should just be that the input won’t be considered pressed untill the input value is greater than the dead zone.

I guess that it’s kinda like a hidden if statement for input

Var deadzone : float = 0.5

If input value  <= deadzone:
       Pass
Elif input value > deadzone:
       #insert code here

So even though the engine constantly checks the inputs value it just won’t do anything until it’s past the deadzone

1 Like

If that’s really how it’s supposed to work, which I don’t really know because it’s my first time using, how am I getting values below the deadzone value if my stick is not even near it?

Is my godot already broken or did I just messed up something that early on my project? The deadzones values that I’m putting are really doing nothing, I might try testing this on a new project to see if there’s really something wrong here.

But thanks for confirming how it’s supposed to work! Was really confused about this.

// Circular length limiting and deadzone.
float length = vector.length();
if (length <= p_deadzone) {
	return Vector2();
} else if (length > 1.0f) {
	return vector / length;
} else {
	// Inverse lerp length to map (p_deadzone, 1) to (0, 1).
	return vector * (Math::inverse_lerp(p_deadzone, 1.0f, length) / length);
}

Here’s the actual engine soure code, you can see it retruns a value from 0 to 1. a deadzone of 0.5 with an input of 0.5 results in 0

2 Likes

Your welcome. I’d say put an Input.is_action_pressed() or even just_pressed() and just play around with the deadzone by changing it and see when it prints the message. The fact that it givse you a value even if it’s below the deadzone should mean nothing.

1 Like

Thanks for further confirming it, will try to send an issue to github because this is really unexpected behavior like I’ve shown here and if there is a solution for it I will update here

3 Likes

I have the same problem and wonder when there is going to be a fix available. @Bruz , can you please link the issue you’ve created? I only found something like Deadzone slider not working in input map menu · Issue #95223 · godotengine/godot · GitHub but this is only for the slider in the Input Map… nevermind, I found it:
Input.get_vector() incorrectly uses joypad axis when using keyboard · Issue #55264 · godotengine/godot · GitHub

It’s still open unfortunately, but there are workarounds of course, which are hinted at in the thread. I’m not yet entirely sure how to do it but I’m positive I’ll find a way.

EDIT: What I ended up using in the physics_process() of the Player:

	var input_vector = Input.get_vector("keyboard_left", "keyboard_right", "keyboard_up", "keyboard_down")

	# To ignore controller input when using keyboard (see https://github.com/godotengine/godot/issues/55264)
	if input_vector:
		facing_direction = input_vector
		rotate_to_direction(facing_direction)
	elif Input.get_vector("left", "right", "up", "down"):
		input_vector = Input.get_vector("left", "right", "up", "down")
		facing_direction = input_vector
		rotate_to_direction(facing_direction)