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

How would you a key that you can hold?

I want to create a magic attack that when you hold a key, you charge it up. However, i'm not sure how to do this using UserInputService...

I've tryed using if statements but that didn't work.

local UIS = game:GetService("UserInputService")
UIS.InputBegan:Connect(function(input, typing)
   if typing then return end
   if input.KeyCode == Enum.KeyCode.R then
	if input.KeyCode == Enum.KeyCode.R then

2 answers

Use the .InputEnded event to detect when they let the key off:

local uis = game:GetService("UserInputService")

local holding

uis.InputBegan:Connect(function(key,gpe)
	
	if gpe then return end
	
	if key.KeyCode == Enum.KeyCode.R then
		-- started holding
		-- you could do other stuff here
		holding = true
		
	end
	
	while holding and wait() do -- inside event or else if wont detect holding has been changed
	
		-- this will run when holding is true and every 0.033 seconds, you can change that of course
	
	end
	
end)

uis.InputEnded:Connect(function(key,gpe)
	
	if gpe then return end
	
	if key.KeyCode == Enum.KeyCode.R then
		-- the key is not being hold anymore
		-- you could do other stuff here
		holding = false

	end
	
end)

Hope this helped!

6 comments

0

I'd recommend using .Changed instead of a while loop

0

"holding" isn't an object so I believe that is impossible.

0

My point exactly. See my answer below

0

But the while loop suits better, because the .Changed event will only run ONCE, and the while loop will run COUNTINOUSLY when the value is true.

0

That's exactly the problem. It's a waste of resources. There's no need to make it run continuously, when the action will have already been completed with the first iteration. Thus, running it in .Changed improves performance

0

Title of the question: "How would you a key that you can hold?" changed will only run ONCE. And "improves performance" doesn't make any sense, as the loop will only play when necessary (when the value is true, aka. holding the key), NOT ALL THE TIME. That means it won't cause any lag if handled properly. I use a loop in one of my games to detect every second what parts are in 60 region3's (by your

I'd like to build off of what zamd suggested. In general, I agree with his usage of InputEnded, however, I'd even suggest using an actual BoolValue instance in your game to determine the value of holding. This way, you can run .Changed on it! I use this method a lot for issues like yours. Here's an example.

local UIS = game:GetService("UserInputService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local IsHolding = Instance.new("BoolValue")
IsHolding.Name = "IsHolding"
IsHolding.Parent = Player

UIS.InputBegan:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.R then
		IsHolding.Value = true
	end
end)

UIS.InputEnded:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.R then
		IsHolding.Value = false
	end
end)

IsHolding.Changed:Connect(function()
	if IsHolding.Value == true then
		--do action
	else
		--stop action
	end
end)

2 comments

0

It would be better just to set up a function and call it from the events, that way you dont have the added bulk of a boolValue lying around.

0

Either way, you have to know as soon as the value is changed. Your options are .Changed, an endless while loop, or metatables, which seems rather unnecessary. Having an outside function does not address the issue you're describing

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