So I’ve created 2 scripts, one localscript in a folder in startergui and another normal script in a folder in workspace. The local script is supposed to detect a player’s input and use a remote to make the server do something, in this case turn on a function. The issue I’m having is that I need the server to be able to constantly detect if the player is holding the button and if not trigger another function, but I can’t figure out a way to make the server be able to constantly detect if the button is held or not, I’ve tried fixing it multiple times but I can’t.
local script:
UserInputService.InputBegan:Connect(function(Input, keyHeld)
while true do
wait(0.1)
if Db and Input then
if UserInputService:IsKeyDown(Input.KeyCode) then
keyHeld = true
DecorRemote:FireServer(Input.KeyCode, keyHeld)
Db = false
wait(0.1)
Db = true
else
keyHeld = false
DecorRemote:FireServer(Input.KeyCode, keyHeld)
Db = false
wait(0.1)
Db = true
end
end
end
end)
Normal script:
DecorRemote.OnServerEvent:Connect(function(player, Input, keyHeld)
while true do
wait(1)
if Input then
print(keyHeld)
functionOfChoice()
else
functionOfChoiceHere()
end
end
end
end)
(There might look like the spacing is weird or there are extra ends, thats because I had to remove some things in order to not leak the script)
UserInputService.InputBegan:Connect(function(Input, Processed)
if Processed then return end
if Input.KeyCode == Enum.KeyCode.X then
-- if the key pressed (thats given above) then do this
end
end)
I would instead advise to try something like this, and also don’t use while wait() do loop in there and instead do it seperately if the keyHeld value is true then do the necessary things you need.
Also your script doesn’t register because on the event UserInputService.InputBegan it gives 2 arguments (the input, and if it was processed) and you cannot change it within the script.
Alternatively in some cases you can do a loop and check if the key is down.
local keyHeld = false
while task.wait(1) do --// waits every second to check
if UserInputService:IsKeyDown(Enum.Keycode.X) then
keyHeld = true
else
keyHeld = false
end
end
-- Services --
local UserInputService = game:GetService('UserInputService')
-- Variables --
local Key = Enum.KeyCode.X
local HoldDuration = 1
local HoldingTask = nil
-- Functions --
local function Hold (): nil
task.wait(HoldDuration)
print(('You held the %s key for %i seconds!'):format(Key.Name, HoldDuration))
end
local function OnInputBegan (Input: InputObject): nil
local KeyCode = Input.KeyCode
if KeyCode ~= Key then return end
HoldingTask = task.spawn(Hold)
end
local function OnInputEnded (Input: InputObject): nil
local KeyCode = Input.KeyCode
if KeyCode ~= Key then return end
if HoldingTask then task.cancel(HoldingTask) end
end
-- Code --
UserInputService.InputBegan:Connect(OnInputBegan)
UserInputService.InputEnded:Connect(OnInputEnded)
Explanation:
Every time the UserInputService detects that an input has started, it checks if the input that started is the same as the key you want to hold. After that it starts a function on a different thread, making it run independently from the other code.
If the UserInputService detects that the user released the desired key, it cancels that thread.
Hopefully this explanation is good enough for you to understand (as I normally don’t explain things haha). If you have any question please ask!
So this wouldn’t really work because I need the functions to trigger on the server-side and so I need the server to also check if the right key is being held. Also seperate functions need to trigger if the player stops holding the designated key
Thank you tho
To my knowledge, the server can’t check if the player is holding a key, as that gets handled client-wise.
If you want to send a signal to the server whenever the key has been held for x amount of time, or when it is unpressed, you can use remote events!
For example:
-- Services --
local UserInputService = game:GetService('UserInputService')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
-- Variables --
local OpenDoorEvent = ReplicatedStorage.OpenDoorEvent
local CloseDoorEvent = ReplicatedStorage.CloseDoorEvent
local Key = Enum.KeyCode.X
local HoldDuration = 1
local HoldingTask = nil
-- Functions --
local function Hold (): nil
task.wait(HoldDuration)
-- Send signal to the server to open door after holding key
OpenDoorEvent:FireServer()
end
local function OnInputBegan (Input: InputObject): nil
local KeyCode = Input.KeyCode
if KeyCode ~= Key then return end
HoldingTask = task.spawn(Hold)
end
local function OnInputEnded (Input: InputObject): nil
local KeyCode = Input.KeyCode
if KeyCode ~= Key then return end
if HoldingTask then task.cancel(HoldingTask) end
CloseDoorEvent:FireServer() -- Send signal to the server to close the door
end
-- Code --
UserInputService.InputBegan:Connect(OnInputBegan)
UserInputService.InputEnded:Connect(OnInputEnded)
maybe handle it with boolean and InputEnded event?
UserInputService.InputBegan:Connect(function(k, g)
if g then return end
if k.KeyCode == Enum.KeyCode.YOURKEY then
specialbool = true
end
end)
UserInputService.InputEnded:Connect(function(k, g)
if g then return end
if k.KeyCode == Enum.KeyCode.YOURKEY then
specialbool = false
end
end)
-- coroutine to check boolean without yielding script
coroutine.resume(coroutine.create(function()
while task.wait(1) do
if specialbool == true then
-- code
end
end
end))
Your script checks every second if the key is being pressed down, resulting in it running the code every second when the key is down and running the code without it being held down for x amount of time.
The main goal is, in fact, not reached. OP asked for a function to run whenever a key is held down for a set amount of time. Using a while loop is not the solution. If you time it right, you can run it the moment you press the key, or wait the entire second. I don’t prefer to gamble for my keypresses.