Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How can I prevent a while loop from running twice?

Asked by 3 years ago

So I created an extremely messy script (this is a part of it), basically the controller of a GUI Object, it does work as expected, but when I press the w key twice, it seems to run the while loop again, resulting in double speed for the GUI Object.

userInputService.InputBegan:Connect(function(input)
    if input.KeyCode == Enum.KeyCode.W then
        while wait(0.5) do
            frame.Position += UDim2.new(0,0,-0.05,0)
        end
    end
end)

2 answers

Log in to vote
0
Answered by
TGazza 1336 Moderation Voter
3 years ago

looking at the above answer you're almost correct. Try this:

local userInputService = game:GetService("UserInputService")

local FramePos = UDim2.new(0,0,0,0)
local YScale = 0

local Key = nil
local oldKey = nil 
local NewKeyPressed = false

userInputService.InputBegan:Connect(function(input)
    Key = input.KeyCode

    if(Key ~= oldKey) then
        NewKeyPressed = true
        oldKey = Key
    else
        NewKeyPressed = false
    end     
end)

while true do
    if(NewKeyPressed == true) then

        if(Key == Enum.KeyCode.W) then
            YScale = -0.05
        else
            YScale = 0
        end
        NewKeyPressed = false
    end
    FramePos = FramePos + UDim2.new(0,0,YScale,0)
    print(FramePos)
    wait(0.5)
end

Firstly if you have your while loop inside your InputBegin Event, as you press on the key w once all is good but as you spam w the loop will be fired multiple times causing your framePosition to move quicker and quicker each W key press.

So what I've come up with is a way to stop this by removing the loop from the event function and made it a global loop at the end of the script. Then I've made a simple memory to record the last key press via Key and oldKey whereas if they are different from it's a new key being pressed. I then recode this change and change the oldKey to the current Key value.

I've also changed the way you would move the frame, rather than changing it directly, I've made a YScale value and change that instead. So you would have better control and understanding on what we're changing.

I then fire up the loop each 0.5 of a sec and check to see if NewKeyPressed == true, if it is then we add the YScale to our frame position.

If you wanted the frame to move faster with each press of the key w then move the loop back inside the Event

Hope this helps! :)

0
Thanks! After a bit of adjustion, I was able to make it work :) SuperLittleAdmin 257 — 3y
Ad
Log in to vote
0
Answered by 3 years ago

i believe you don't have to use a while loop!

but if you wanted to use a while loop, use break

    userInputService.InputBegan:Connect(function(input)
        if input.KeyCode == Enum.KeyCode.W then
            while wait(0.5) do
                frame.Position += UDim2.new(0,0,-0.05,0)
            break
            end     
        end
    end)

i believe u could do this instead:

    userInputService.InputBegan:Connect(function(input)
        if input.KeyCode == Enum.KeyCode.W then
        wait()
             frame.Position+=Udim2.new(0,0,-0.05,0)  
        end
    end)
0
I use a while loop because I want it to keep moving in that direction until another key is pressed, so using break will, well, break what I intended to do. SuperLittleAdmin 257 — 3y

Answer this question