Roblox stick drift bug

I have a custom input module that allows me to bind various inputs to various string keys representing actions. Inside the module, I have this to set controller input:

CAS:BindAction("ThumbstickMoved", function(ActionName, InputState: Enum.UserInputState, Input)
	if ActionName == "ThumbstickMoved" and InputState == Enum.UserInputState.Change then
		
		local X = (math.abs(Input.Position.X) > 0.1 and Input.Position.X or 0.1)-0.1
		local Y = (math.abs(Input.Position.Y) > 0.1 and Input.Position.Y or 0.1)-0.1
		GamepadLook = Vector2.new(X, -Y) * 6
		if GamepadLook.Magnitude < .05 then GamepadLook = Vector2.new() end
	end
end, false, Enum.KeyCode.Thumbstick2)

It works okay, but it has a problem. This function only runs when input changes. when the player lets go of their thumbstick, the game reads the input until the stick stops moving, and then it no longer fires the inputchanged event. When letting go of the thumbstick, the last Input.Position output when letting go is never 0,0. This means that a deadzone is necessary.

Issue: The last ending position when letting go of the stick depends on the speed at which it returns to resting position. The faster it flicks back, the more volatile that ending position is. As a result, even when having a deadzone like this, the player still gets stick drift when flicking the stick, because the input never returns to 0.

I have tried:

  • using UIS:GetGamepadState() every frame to always have the current position. This does not work as for some reason, this does not update either without the inputchanged event firing. Accessing the position in UIS:GetGamepadState() still has the drift issue
  • increasing the size of the deadzone - Increasing it more makes the controller terrible to control, players can either move massively or not at all

Nothing i do works, please help

I realized that the playermodule is open and accessible, and that the playermodule’s controller input also works perfectly fine. I went digging around in the playermodule and found this handy little function:

local thumbstickCurve do
	local K_CURVATURE = 2 -- amount of upwards curvature (0 is flat)
	local K_DEADZONE = 0.1 -- deadzone

	function thumbstickCurve(x)
		-- remove sign, apply linear deadzone
		local fDeadzone = (math.abs(x) - K_DEADZONE)/(1 - K_DEADZONE)

		-- apply exponential curve and scale to fit in [0, 1]
		local fCurve = (math.exp(K_CURVATURE*fDeadzone) - 1)/(math.exp(K_CURVATURE) - 1)

		-- reapply sign and clamp
		return math.sign(x)*math.clamp(fCurve, 0, 1)
	end
end

When i put the thumbstick inputs through the function like so, everything seems to work fine:

local x = thumbstickCurve( input.Position.X )
local y = thumbstickCurve( input.Position.Y )
		
GamepadLook = Vector2.new(x, -y) * 6

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.