Hello, wondering if anyone could help me with this issue I’ve been having on a lot of my scripts:
I have an input ended function inside of a input began function and if the input ended after I clicked the key 10 times, the input ended prints “F has been ended” 10 times, instead of just once. I don’t know of any ways to completely end the entire input began function if the input has already ended, any help would be appreciated.
My script:
local UserInputService = game:GetService("UserInputService")
UserInputService.InputBegan:Connect(function(Input)
if Input.KeyCode == Enum.KeyCode.F then
local Holding = true
UserInputService.InputEnded:Connect(function(Input)
if Input.KeyCode == Enum.KeyCode.F then
Holding = false
print("F has been ended")
end
end)
print("F has been pressed")
while Holding do
wait(1)
if Holding then
print("Still holding")
end
end
end
end)
So, you may be looking for :Disconnect(). Here is an example of how to use it:
local connection
connection = workspace.ChildAdded:Connect(function(thing)
if thing.Name == "Stop" then
connection:Disconnect() -- disconnect the current function! It won't fire again.
end
end
You could use this to disconnect the InputBegan function, for example, if you only wanted to run it once.
(Edit: first method was already explained, but I believe the second method is the best way to go)
Notice how every time F is pressed, you’re creating another connection to check if F is released?
Basically, what happens is every time you let go of F, that function is fired, as well as all the previous ones that were called. You either have to clean this up or separate the events. There’s multiple ways to do this:
Disconnect the event after F is released
UIS.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.F then
local holding = true
local connect = nil
connect = UIS.InputEnded:Connect(function(input2)
if input2.KeyCode == Enum.KeyCode.F then
holding = false
connect:Disconnect()
end
end)
while holding do
print"Still holding"
wait(1)
end
end
end)
Separate the events:
local holdingF = false
UIS.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.F then
holding = true
while holding do
wait(1)
end
end
end)
UIS.InputEnded:Connect(function(input)
if input.KeyCode == Enum.KeyCode.F then
holding = false
end
end)
Separating the event is a far better idea than connecting it in InputBegan. It’s pointless to include the ended event in the begin event.
You can also use InputChanged to get Begin and Ended states all in one go.
local holding = false
UserInputService.InputChanged:Connect(InputObject, GameProcessedEvent)
if InputObject.KeyCode == Enum.KeyCode.F then
holding = (InputObject.UserInputState == Enum.UserInputState.Begin)
while holding do -- Will not run if holding is false
wait(1)
end
end
end)
holding becomes true only if UserInputState is begin, all other instances make it false. Realistically, you wouldn’t need it to be true for any other UserInputState. I like this version a lot because you only connect one function and handle it right from the parameters there.