Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How can I prevent a while loop from running twice?

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

✓ Accepted answer

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

1 comment

0

Thanks! After a bit of adjustion, I was able to make it work :)

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)

1 comment

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.

This discussion is preserved as it was. New answers, comments, and votes are closed.