Make UserInputSystem sense when a button is held down instead of when a button is pressed

I have a vehicle control system where there is a local script in StarterPlayerScripts that sends a signal of player input service to the script in the vehicle. The problem is that, while the vehicle does what it’s supposed to when a button is pressed, it only does it once every time the key is pressed. How do I make the local script sense when a button is held down and make the vehicle turn constantly when the button is held down?

Here’s the setup:


(New is the ServerScript shown below)

And here are the scripts:
ServerScript:

local remote = game.ReplicatedStorage.Turning
local seat = script.Parent 
local Gyro = seat.BodyGyro

remote.OnServerEvent:Connect(function(player,button) 
	local chara = player.Character 
	if chara then 
		local human = chara:FindFirstChildWhichIsA("Humanoid") 
		if human and human == seat.Occupant then --check mentioned above 
			if button == "J" then 
				Gyro.CFrame = Gyro.CFrame*CFrame.fromEulerAnglesXYZ(-0.1,0,0)
			elseif button == "U" then 
				Gyro.CFrame = Gyro.CFrame*CFrame.fromEulerAnglesXYZ(0.1,0,0)
			elseif (script.Parent.Steer == 0) then
				Gyro.CFrame = Gyro.CFrame
			end 
		end 
	end 
end) 

LocalScript:

local remote = game.ReplicatedStorage:WaitForChild("Turning") 
local UserInputService = game:GetService("UserInputService") 

UserInputService.InputBegan:Connect(function(key) 
	if key.KeyCode == Enum.KeyCode.U then
		remote:FireServer("U")
	elseif key.KeyCode == Enum.KeyCode.J then
		remote:FireServer("J")
	end 
end)
1 Like

You can just add a variable and a loop to run until UserInputService.InputEnded is fired:

local turning = false

UserInputService.InputBegan:Connect(function(key) 
	if key.KeyCode == Enum.KeyCode.U then
		turning = true
		while turning do
			wait()
			remote:FireServer("U")
			UserInputService.InputEnded:Connect(function(key)
				if key == Enum.KeyCode.U then
					turning = false
				end
			end)
		end
	elseif key.KeyCode == Enum.KeyCode.J then
		turning = true
		while turning do
			wait()
			remote:FireServer("J")
			UserInputService.InputEnded:Connect(function(key)
				if key == Enum.KeyCode.J then
					turning = false
				end
			end)
		end
	end 
end)

UserInputService has a neat function you can use to detect when a key is pressed down. You can use a while loop or other loop and wait until it is no longer being held down. Here’s an example code with a simple while loop:

local UIS = game:GetService("UserInputService")

UIS.InputBegan:Connect(function(Input, GPE)
if GPE then return end -- If it's typed while in chat or a textbox, ignore it.

    if Input.KeyCode == Enum.KeyCode.U then
        remote:FireServer("U") -- Tell the server that U is being held down.
            while UIS:IsKeyDown(Enum.KeyCode.U) do
                wait() -- Wait until it's no longer being pressed
            end
        remote:FireServer("Stop") -- Stop the server from steering
    end

end)

You don’t want to constant fire events while it’s held down, rather tell the server its turning and then tell the server when you stop turning, that way, you cut down on bandwidth usage. You can read more on the UserInputService below, and :IsKeyDown() as well:

:IsKeyDown()
UserInputService

I hope this helps!

Edit: Made code more readable.

1 Like