Detecting when a controller's thumbstick is held, not just pressed

I’m having a lot of trouble figuring out how to keep a loop going as long as a certain direction is held on a thumbstick.

uis.InputChanged:Connect(function(input, gameProcessedEvent)
	if input.KeyCode == Enum.KeyCode.Thumbstick1 then
		if input.Position.X > 0.2 then
			if flying then
				heat += 1
				orientationFixer.CFrame *= CFrame.Angles(0, 0, math.rad(-2.5))
				local hrpVector = hrp.CFrame.UpVector
				velocityGiver.VectorVelocity = calculateSpeed()
				monitorHeat()
			end
			task.wait(0.01)
		elseif input.Position.X < -0.2 then
			if flying then
				heat += 1
				orientationFixer.CFrame *= CFrame.Angles(0, 0, math.rad(2.5))
				local hrpVector = hrp.CFrame.UpVector
				velocityGiver.VectorVelocity = calculateSpeed()
				monitorHeat()
			end
			task.wait(0.01)
		end
		if input.Position.Y > 0.2 then
			if flying then
				heat += 1
				orientationFixer.CFrame *= CFrame.Angles(math.rad(-2.5), 0, 0)
				local hrpVector = hrp.CFrame.UpVector
				velocityGiver.VectorVelocity = calculateSpeed()
				monitorHeat()
			end
			task.wait(0.01)
		elseif input.Position.Y < -0.2 then
			if flying then
				heat += 1
				orientationFixer.CFrame *= CFrame.Angles(math.rad(2.5), 0, 0)
				local hrpVector = hrp.CFrame.UpVector
				velocityGiver.VectorVelocity = calculateSpeed()
				monitorHeat()
			end
			task.wait(0.01)
		end
	end
end)

Course, I’ve tried both Delta and Position, but have seen a little more “accuracy” with Position. When I try to use uis:IsGamepadButtonDown() with Enum.Keycode.Thumbstick1Up (or any direction), nothing comes out of it. And without that, I haven’t a clue how to loop it. This:

			if flying then
				heat += 1
				orientationFixer.CFrame *= CFrame.Angles(0, 0, math.rad(-2.5))
				local hrpVector = hrp.CFrame.UpVector
				velocityGiver.VectorVelocity = calculateSpeed()
				monitorHeat()
			end
			task.wait(0.01)

…should be what’s looped. Can’t figure this out for the life of me. I’ve been looking around for hours but I still can’t figure out how to just detect it being held in a direction. Also tried adding variables that change based on the last direction pressed, and it just kept stacking loops, so that wasn’t it. The keyboard counterpart for this code works excellently with :IsKeyDown(), is there really no way to use that Thumbstick1Up enum?

It’s L3 .. R3 is the right one, and that one don’t work as well.. if at all.

local userInputService = game:GetService("UserInputService")
local run = game:GetService("RunService")

local leftHeld = false

userInputService.InputBegan:Connect(function(input, processed)
	if processed then return end
	if input.KeyCode == Enum.KeyCode.ButtonL3 then
		leftHeld = true
	end
end)

userInputService.InputEnded:Connect(function(input, processed)
	if input.KeyCode == Enum.KeyCode.ButtonL3 then
		leftHeld = false
	end
end)

run.RenderStepped:Connect(function()
	if leftHeld then
		print("Left thumbstick held")
	end
end)

I see, the right is locked to the camera view.

ContextActionService
KeyCodes

Unless you were talking to the guy who deleted his posts (no idea, I wasn’t there), seems like you’ve misunderstood my post or skipped the majority of its content. I’m not looking to find when the left stick is pressed down, I’m looking to find when the stick is held either up, down, left, or right. Like, you know, for instance, basic movement. You hold the stick in the direction you want to go. That’s what I’m trying to figure out, but I can’t find a reliable way of keeping track of when the stick is held in a certain direction.

It said: Detecting when a controller’s thumbstick is held, not just pressed

I guess I may have taken that the wrong way.. But hey I figured out something way harder.. :rofl:
ya.. anyways:

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local hrp = character:WaitForChild("HumanoidRootPart")

local flying = true
local heat = 0
local overheated = false
local overheatThreshold = 100
local overheatResetTime = 3
local overheatTimer = 0
local deadzone = 0.2
local rotationSpeed = 100
local thumbstickPos = Vector2.zero

local velocityGiver = { VectorVelocity = Vector3.zero }

local function calculateSpeed()
	return hrp.CFrame.LookVector * 50
end

UserInputService.InputChanged:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.Gamepad1 and input.KeyCode == Enum.KeyCode.Thumbstick1 then
		thumbstickPos = input.Position
	end
end)

UserInputService.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.Gamepad1 and input.KeyCode == Enum.KeyCode.Thumbstick1 then
		thumbstickPos = Vector2.zero
	end
end)

RunService.RenderStepped:Connect(function(dt)
	if not flying then return end

	local x, y = thumbstickPos.X, thumbstickPos.Y
	local magnitude = 0
	if math.abs(x) > deadzone then magnitude += math.abs(x) end
	if math.abs(y) > deadzone then magnitude += math.abs(y) end

	if not overheated then
		if magnitude > 0 then
			local xAngle = math.rad(rotationSpeed * x * dt)
			local yAngle = math.rad(rotationSpeed * y * dt)
			hrp.CFrame *= CFrame.Angles(-yAngle, 0, -xAngle)
			velocityGiver.VectorVelocity = calculateSpeed()
			heat += magnitude * dt * 60
		end
		if heat >= overheatThreshold then
			print("Overheated!")
			overheated = true
			overheatTimer = overheatResetTime
		end
	else
		overheatTimer -= dt
		print(string.format("Reset in: %.2f", math.max(overheatTimer,0)))
		if overheatTimer <= 0 then
			heat = 0
			overheated = false
		end
	end
end)

You may not need to know the cooldown or even want one, but for testing I needed to see that everything is really working. I just give you my whole test and let you sort it out.

Stop by to see how this went. I know this script works.. any problems?

We can use UserInputService.InputChanged. to get the current position of the thumbstick and compare it to the dot product of out desired direction and angle to know if we’re in the ‘green zone’.

The red angle is our maxAngle variable and it defines our green zone.
The blue arrows show the direction we want to check in this is our direction variable.
If you’re familiar with the unit circle and unit vectors i don’t think this will be an issue to understand.

local UserInputService = game:GetService("UserInputService")

local direction = Vector2.new(0, 1)
local maxAngle = math.rad(46)

local dotAngle = math.cos(maxAngle)

local function waitForThumbstick1()
	local input
	
	repeat
		input = UserInputService.InputChanged:Wait()
	until input.KeyCode == Enum.KeyCode.Thumbstick1
	
	return input
end

local function isInGreenZone(input: InputObject): boolean
	local currentDirection = Vector2.new(input.Position.X, input.Position.Y)
	
	local dot = direction.Unit:Dot(currentDirection.Unit)

	if dot >= dotAngle then
		return true
	else
		return false
	end
end

while true do
	local input = waitForThumbstick1()
	
	while isInGreenZone(input) do
		print("Holding!")
		-- code here
		task.wait()
	end
end

This was EXACTLY what I was looking to do. Thanks, mate! Helps a lot.

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