Repository: godotengine/godot (language: cpp)

Issue:
New default UI input deadzone of 0.2 causes menuing glitches with analog sticks
### Tested versions

4.4.beta1

### System information

Godot v4.4.beta1 - Windows 10 (build 19045) - Multi-window, 2 monitors - OpenGL 3 (Compatibility) - AMD Radeon RX 6800 (Advanced Micro Devices, Inc.; 32.0.12033.1030) - AMD Ryzen 5 7600X 6-Core Processor (12 threads)

### Issue description

When you release a fully-tilted analog stick, it bounces in the opposite direction and briefly springs back and forth for a moment. This is necessary background to understand the following:

In godot 4.3, the deadzone for UI inputs was 0.5. When releasing a fully-tilted stick, it would sometimes but not always backlash past 0.5 in the opposite direction, so menuing glitches were relatively uncommon. I think it happens only about 20% of the time that I release the stick.

In 4.4, the deadzone is 0.2. This is small enough that I basically always get a false input when suddenly releasing a fully-tilted analog stick. Sometimes multiple in a row!

4.4: 

https://github.com/user-attachments/assets/f129e5df-e1b3-4912-b603-641872a6f2f5

4.3:

https://github.com/user-attachments/assets/9381886b-5e2d-47a8-be76-cec0ebb9eb05

### Steps to reproduce

See above.

### Minimal reproduction project (MRP)

N/A but you can use the project from https://github.com/godotengine/godot/issues/103318 if you want to replicate my above videos


Discussion / hints:
For reference I'm using a dualsense (ps5 controller) that isn't particularly busted but isn't brand new either. So the amount of stick springiness I'm experiencing is somewhat surprising but not unusual, and not indicative of a dying/dead joystick.
For more reference I used a joystick tester to test the threshold/deadzone value for left-stick menu navigation in various games I have installed:

Honkai Star Rail: 55%
Genshin Impact: 57%
Final Fantasy X HD Remaster: 82%
Final Fantasy 1 Pixel Remaster: 52~53%
Dragon Quest Builders 2: no analog stick menu navigation
Phantom Brave PC: 82.5%ish
Fairy Fencer F: Refrain Chord: 58%
Klonoa (launcher): 54%
Klonoa Door To Phantomile (PC port): 50%
Atelier Sophie DX: no analog stick menu navigation
Atelier Ryza: 18%; also, navigating the settings menus is REALLY annoying. it's actively difficult to not accidentally trigger left/right and cause the value of a setting to change. On some menus I can get the backlash input glitch to happen.
Utawarerumono: Mask of Deception: 38%
Final Fantasy XV Windows Edition: no analog stick menu navigation
Tales of Vesperia: Definitive Edition: 64%

Almost all of these are above 50%. Games that probably went through aggressive AAA-esque console release QA testing generally have thresholds in the 65% to 85% range. The only one close to 20% is Atelier Ryza, where it causes problems.

Trivia: the dualsense has a feature where if I hold the PS button and move the analog stick up or down it changes the volume of my PC's default audio device. The tilt threshold where this happens is at 95%.
The proposal for that change had tests done on a bunch of AAA games with much lower deadzone values that the ones you measured: https://github.com/godotengine/godot-proposals/issues/7069#issuecomment-1623721743

I noticed most of the games you tested seem to be Japanese or Chinese, while the ones in the linked comment are US/European. Would that be a cultural difference maybe in how people use the analog stick?
Perhaps it's a difference between UI vs ingame deadzones?
I'm not sure which https://github.com/godotengine/godot-proposals/issues/7069#issuecomment-1623721743 tested, but it sounds like @wareya is mostly concerned about UI use.
Yes, it's a difference between UI and ingame deadzones specifically. This issue is not about the ingame deadzone behavior, only UI.
(The games I cited have relatively normal ingame deadzones in the 5%~30% range.)
The problem then is likely that Godot only has a single default deadzone value for both UI and in-game events. It seems like the default was change to be better for in-game events, but also affected UI ones. Maybe it could be changed back to `0.20` for `ui_*` events specifically.
See my comment here: https://github.com/godotengine/godot/pull/97281#issuecomment-2688391556
I think it would be best to not have a project-level UI threshold setting; sometimes for different inputs you want different thresholds for UI actions, in particular triggers and sticks feel very different. It would make sense for me to play a game where the trigger threshold is at 35% and the stick threshold is at 80%, for example. (Yes, lots of games use triggers, not just bumpers, for menu navigation these days.)

For the CharacterBody3D script, it could be changed to use the optional argument of `Input.get_vector` that lets it specify the deadzone.

For the 2D one, `Input.get_axis` doesn't have a deadzone argument, but maybe it could use `get_vector` with an explicit deadzone and just use the x component?


Fix patch:
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index a6725ce38bd2..e4cc0f9c03b1 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -1439,7 +1439,7 @@ void ProjectSettings::_add_builtin_input_map() {
 			}
 
 			Dictionary action;
-			action["deadzone"] = Variant(InputMap::DEFAULT_DEADZONE);
+			action["deadzone"] = Variant(InputMap::DEFAULT_TOGGLE_DEADZONE);
 			action["events"] = events;
 
 			String action_name = "input/" + E.key;
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index bd793ef6b8fc..6e8cdc4b8e46 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -1104,7 +1104,7 @@ JoyAxis InputEventJoypadMotion::get_axis() const {
 
 void InputEventJoypadMotion::set_axis_value(float p_value) {
 	axis_value = p_value;
-	pressed = Math::abs(axis_value) >= InputMap::DEFAULT_DEADZONE;
+	pressed = Math::abs(axis_value) >= InputMap::DEFAULT_TOGGLE_DEADZONE;
 	emit_changed();
 }
 
diff --git a/core/input/input_map.h b/core/input/input_map.h
index 0479d45c57b5..520c10c46e06 100644
--- a/core/input/input_map.h
+++ b/core/input/input_map.h
@@ -55,6 +55,8 @@ class InputMap : public Object {
 	};
 
 	static constexpr float DEFAULT_DEADZONE = 0.2f;
+	// Keep bigger deadzone for toggle actions (default `ui_*` actions, axis `pressed`) (GH-103360).
+	static constexpr float DEFAULT_TOGGLE_DEADZONE = 0.5f;
 
 private:
 	static InputMap *singleton;


Test patch: