How do I make my frame movement script loop?

So, this is an extension to another post I made yesterday. I completely re-did my script and it works! But I have to spam click WASD in order to move. How do I make it so when I hold down a key, the frame moves.

Here’s my new script:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local debounce = false

--D
	game:GetService("UserInputService").InputBegan:Connect(function(inputObject, gameProcessedEvent)
	if inputObject.KeyCode == Enum.KeyCode.D then
		if debounce == false then
			debounce = true
			script.Parent.Position = script.Parent.Position + UDim2.new(0.01,0,0)
		end
		wait(0.5)
		debounce = false
	end 
end)


--W
game:GetService("UserInputService").InputBegan:Connect(function(inputObject, gameProcessedEvent)
	if inputObject.KeyCode == Enum.KeyCode.W then
		if debounce == false then
			debounce = true
			script.Parent.Position = script.Parent.Position - UDim2.new(0,0,0.01)
		end
		wait(0.5)
		debounce = false
	end 
end)

--A
game:GetService("UserInputService").InputBegan:Connect(function(inputObject, gameProcessedEvent)
	if inputObject.KeyCode == Enum.KeyCode.A then
		if debounce == false then
			debounce = true
			script.Parent.Position = script.Parent.Position - UDim2.new(0.01,0,0)
		end
		wait(0.5)
		debounce = false
	end 
end)

--S
game:GetService("UserInputService").InputBegan:Connect(function(inputObject, gameProcessedEvent)
	if inputObject.KeyCode == Enum.KeyCode.S then
		if debounce == false then
			debounce = true
			script.Parent.Position = script.Parent.Position + UDim2.new(0,0,0.01)
		end
		wait(0.5)
		debounce = false
	end 
end)
1 Like

you only fire the script on inputbegan, and only once.
you need some kind of loop function to keep the frame moving while the button has not been released yet
(i say… not been released yet as that would be your trigger… not while holding down)

1 Like

Got an idea what you could do. As the events only fire when the input begins and not as they are hold you have to deal with it differently. Maybe you can shrink down the code a bit by using this. It simply has the move vectors in the ‘keys’ table stored and if they are held they are added to the ‘pressed’ table and removed when released.

local UserInputService = game:GetService("UserInputService")

local keys = {
	[Enum.KeyCode.W] = -UDim2.new(0, 0, 0.01, 0),
	[Enum.KeyCode.A] = -UDim2.new(0.01, 0, 0, 0),
	[Enum.KeyCode.S] = UDim2.new(0, 0, 0.01, 0),
	[Enum.KeyCode.D] = UDim2.new(0.01, 0, 0, 0)
}

local pressed = {}

UserInputService.InputBegan:Connect(function(inputObject, gameProcessedEvent)
	local key = inputObject.KeyCode
	if keys[key] then
		pressed[key] = keys[key]
	end 
end)

UserInputService.InputEnded:Connect(function(inputObject, gameProcessedEvent)
	local key = inputObject.KeyCode
	if keys[key] then
		pressed[key] = nil
	end 
end)

Shrunken that down you just can check every frame inside the pressed table if a key is down and add that value to the frame’s position.

local RunService = game:GetService("RunService")

RunService:BindToRenderStep("move", Enum.RenderPriority.Camera.Value, function()
	local move = UDim2.new()
	for _, v in pairs(pressed) do
		move += v
	end
	script.Parent.Position = script.Parent.Position + move
end)
1 Like