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?
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)
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: