WASD Movement on UI

I’m trying to make a WASD System but on UI. I’ve managed to script it so it moves left and right when a key is pressed, but thats it. If I press A, it goes left once, and if I press D, it goes right once. My issue is that I want the UI Image to move when A or D are being held down, and continuesly move to an according position (left or right).

This is the current A Button script:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
script.Parent.Position = UDim2.new(0.014, 0,0.714, 0)

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

This is the current D Button script:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
script.Parent.Position = UDim2.new(0.014, 0,0.714, 0)

local debounce = false
game:GetService("UserInputService").InputBegan:Connect(function(inputObject, gameProcessedEvent)
	if inputObject.KeyCode == Enum.KeyCode.D then
		if debounce == false then
			debounce = true
			print("pressed D")
			script.Parent.Position = script.Parent.Position + UDim2.new(0.01,0,0)
		end
		wait(0.05)
		debounce = false
	end
end)
game:GetService("UserInputService").InputEnded:Connect(function(inputObject, gameProcessedEvent)
	if inputObject.KeyCode == Enum.KeyCode.D then
		print("unpressed D")
	end 
end)
1 Like

You should have a loop inside the movement, like this:

local UserInputService = game:GetService("UserInputService")

local A_pressed = false

UserInputService.InputBegan:Connect(function(inp, processed)
	if inp.KeyCode == Enum.KeyCode.A then
		if A_pressed then return end -- Abort on debounce
		A_pressed = true
		repeat
			task.wait() -- Add in appropriate delay
			script.Parent.Position = script.Parent.Position - UDim2.new(0.01,0,0)
		until not A_pressed
	end
end)


UserInputService.InputEnded:Connect(function(inp, processed)
	if inp.KeyCode == Enum.KeyCode.A then
		A_pressed = false
	end
end)

Note: You could replace if debounce with if A_pressed since A_pressed will be true if debounce is true.

Edit: Added task.wait(), thanks for the reminder @WoTrox!

2 Likes

I would do something like this

local AHeld = false
game:GetService("UserInputService").InputBegan:Connect(function(inputObject, gameProcessedEvent)
	if inputObject.KeyCode == Enum.KeyCode.A then
		AHeld = true
	end
end)

game:GetService("UserInputService").InputEnded:Connect(function(inputObject, gameProcessedEvent)
	if inputObject.KeyCode == Enum.KeyCode.A then
		AHeld = false
	end 
end)

coroutine.wrap(function() --maybe using RenderStepped or Heartbeat would be better, but I will use a loop rn
	while wait() do
		if AHeld then
			--move it left a little
		end
	end
end)()
1 Like

i tried it but it doesn’t work…did i mess up perhaps?

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
script.Parent.Position = UDim2.new(0.014, 0,0.714, 0)

local debounce = false
local A_pressed = false

UserInputService.InputBegan:Connect(function(inp, processed)
	if inp.KeyCode == Enum.KeyCode.A then
		A_pressed = true
		repeat
			game:GetService("UserInputService").InputBegan:Connect(function(inputObject, gameProcessedEvent)
				if inputObject.KeyCode == Enum.KeyCode.A then
					if debounce == false then
						debounce = true
						print("pressed A")
						script.Parent.Position = script.Parent.Position - UDim2.new(0.01,0,0)
					end
					wait(0.05)
					debounce = false
				end
			end)
			game:GetService("UserInputService").InputEnded:Connect(function(inputObject, gameProcessedEvent)
				if inputObject.KeyCode == Enum.KeyCode.A then
					print("unpressed A")
				end 
			end)-- Movement code
		until not A_pressed
	end
end)


UserInputService.InputEnded:Connect(function(inp, processed)
	if inp.KeyCode == Enum.KeyCode.A then
		A_pressed = false
	end
end)

You put the whole InputBegan event inside the loop. Yu only have to put the script.Parent.Position = script.Parent.Position - UDim2.new(0.01,0,0) part inside it. But i would recommend adding a wait() too, and also using a coroutine like I did to keep the code running outside the loop too. Or just use the Heartbeat function

also tried, put it exactly how you showed and still no results…

1 Like

Just have it like this:


local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
script.Parent.Position = UDim2.new(0.014, 0,0.714, 0)

local debounce = false
local A_pressed = false

UserInputService.InputBegan:Connect(function(inp, processed)
	if inp.KeyCode == Enum.KeyCode.A then
		A_pressed = true
		repeat
		
					if debounce == false then
						debounce = true
						print("pressed A")
						script.Parent.Position = script.Parent.Position - UDim2.new(0.01,0,0)
					end
					wait(0.05)
					debounce = false
         until not A_pressed
    end
end)
			
			

UserInputService.InputEnded:Connect(function(inp, processed)
	if inp.KeyCode == Enum.KeyCode.A then
		A_pressed = false
	end
end)

I edited my first comment to contain your movement code as well. Hope this makes more sense.

It doesn’t do anything when I press A
robloxapp-20220623-1549313.wmv (75.7 KB)

Try the first reply to this topic, he edited it

Right now this will make the UI teleport out of the screen, because it moves to the left continuously instantly. Make sure you add a wait(0.1) to slow it down

tried it aswell, still nothing. I think the problem is cause UserInputService is underlined, but idk why it is

@WoTrox @domboss37 @ifkpop (sorry for tagging btw), Your Scripts are probably be working, but i think the issue is that the UserInputService is underlined, as seen in the photo. Why?

Your UserInputService doesn’t exist. Add this to the beginning of the script

local UserInputService = game:GetService("UserInputService")

You first have to get the service from Roblox to be able to use it. That’s what that line does, it tells the script that it needs to use the User Input Service, which you store in a variable called “UserInputService”

Also, make sure its in a LocalScript, not a “normal” script

Thanks, I’m kinda a beginner scripter if you couldn’t tell already. Now it does work, but when i hold A down, the ui moves once

Since you don’t need to know when the keys are released, you can boil this down to a few checks in a RenderStepped loop:

RunService.RenderStepped:Connect(function()
    if UserInputService:IsKeyDown(Enum.KeyCode.W) then
        print"W down"
    end
    
    if UserInputService:IsKeyDown(Enum.KeyCode.A) then
        print"A down"
    end
    
    if UserInputService:IsKeyDown(Enum.KeyCode.S) then
        print"S down"
    end
    
    if UserInputService:IsKeyDown(Enum.KeyCode.D) then
        print"D down"
    end
end)

A few things to note,
1): You need to create a variable called UserInputService

local UserInputService = game:GetService("UserInputService")

2): On line 6 you have a typo in A_pressed. On line 7 you assing A_pressed = false, which you shouldn’t do as that will instantly end the loop.

I’ll just update my code once again to show what I meant with

so…like this?

local UserInputService = game:GetService("UserInputService")
local A_pressed = false

UserInputService.InputBegan:Connect(function(inp, processed)
	if inp.KeyCode == Enum.KeyCode.A then
		if A_pressed then return end -- Abort on debounce
		A_pressed = true
		A_pressed = false
		repeat
			script.Parent.Position = script.Parent.Position - UDim2.new(0.01,0,0)
		until not A_pressed
		A_pressed = true
	end
end)


UserInputService.InputEnded:Connect(function(inp, processed)
	if inp.KeyCode == Enum.KeyCode.A then
		A_pressed = false
	end
end)

it finally workksssss!!! Thank you so much…all of you :happy3:

1 Like

Almost, you need to add a task.wait() here

and remove A_pressed = false and the A_pressed = true after the loop.