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

How would you a key that you can hold?

Asked by
hours2 10
3 years ago

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

Log in to vote
3
Answered by 3 years ago

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!

0
I'd recommend using `.Changed` instead of a `while` loop Gey4Jesus69 2705 — 3y
0
"holding" isn't an object so I believe that is impossible. User#32819 0 — 3y
0
My point exactly. See my answer below Gey4Jesus69 2705 — 3y
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. User#32819 0 — 3y
View all comments (2 more)
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 Gey4Jesus69 2705 — 3y
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 User#32819 0 — 3y
Ad
Log in to vote
0
Answered by 3 years ago

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)
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. Benbebop 1049 — 3y
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 Gey4Jesus69 2705 — 3y

Answer this question