Issue With Hotkey Code

I am attempting to create a GUI which functions in a way that when you press a key on your keyboard, which is Q in this case, a GUI opens, and closes in the same way. However, my script isn’t working, is anyone able to identify the issue?

Here is the code written out if you can’t see in the image:

local frame = script.Parent.Parent.Frame
local hotkey = Enum.KeyCode.Q
local UIS = game.GetService(“UserInputService”)
local open = false

UIS.InputBegan:Connect(function(key)
if key.keyCode == hotkey then
if UIS:GetFocusedTextBox() == nil then
if open == false then
open = true
frame.Visible = open
elseif open == true then
open = false
frame.Visible = open
end
end
end
end)

1 Like

Have you got the script output window open? It would show you any errors you are getting. From a quick glance I can see:

game.GetService("UserInputService")

Roblox’s lua parser does not like using the dot notation for function calling, in fact it throws an error on that line. This line though would parse fine.

local UIS = game:GetService("UserInputService")

Once that is changed that your code should work fine. If it does end up that you don’t have the output window open, I suggest using it, it is very useful for all kinds of output.

1 Like

Throws an error because it’s not receiving the correct amount of arguments. Instance methods follow object-oriented programming styles. The colon passes the DataModel as self to the method GetService: with dot notation, the self parameter is missing and the first argument goes to the UserInputService string, thus why it throws an error.

These two do the exact same thing:

game:GetService("UserInputService")
game.GetService(game, "UserInputService")

While I’m not quite sure what exactly is making the script not work properly since there’s no console screenshots, there’s a few ways to cut down on how this script’s working which could also solve the root issue. For example, since the open variable is only used to determine if the frame should be open or not, this can be shortened to just changing the frame’s visibility to its reverse.

local UserInputService = game:GetService("UserInputService")

local HOT_KEY = Enum.KeyCode.Q
-- I prefer not to have LocalScripts nested so deeply in a hierarchy
-- Would be organisationally cleaner to make it be directly under the Gui
local FRAME = script.Parent.Parent.Frame

UserInputService.InputBegan:Connect(function (inputObject, gameProcessedEvent)
    -- InputBegan fires with gameProcessedEvent as true last I recall, so
    -- actually make use of this parameter. Below is a guard clause.
    if gameProcessedEvent then return end

    if inputObject.KeyCode == HOT_KEY then
        frame.Visible = not frame.Visible
    end
end)
1 Like

You might also want to consider Roblox’s ContextActionService for triggering this feature, so that the function isn’t firing when the player types ‘Q’ in chat.
In this usage, you’ll bind a function to a context action that triggers on specified hotkeys. But like the UserInputService’s InputBegan function, the handler function takes in multiple arguments.

I duplicated OP’s script the best I could in a local environment.

And the only error I get when the code is run is this
image

So perhaps the : is actually this issue?

Does it work as expected when you change the way you call GetService? If so, then yeah, it would just be a simple fix of changing the symbol used to call GetService.

Bonus round on my post with some code improvement tips. :slight_smile:

Yep, it works if I change to a colon.

Looks like we all learnt something here, and went in circles in the process :man_facepalming:

Thanks a lot, this solved the issue. My game has a lot of GUI’s so this is going to help tons. Thanks!

What about GameProcessedEvent?

The typing part wasn’t an issue. The problem was solved by changing the ‘.’ to a colon.

No I know, I wasn’t talking about that. I was just talking about what greatgavin said.

1 Like

Yeah dude, GameProcessedEvent can totally be used to filter out the same behavior. So it’s completely up to the programmer’s discretion. The only difference is that the ContextActionService behaves like a stack, so the handler function only fires if it has context- never needing that extra check.

@1988_YumDeveloper Awesome the initial issue was fixed, lua sure has some crazy syntax. Still your function right now doesn’t account for gameProcessedEvents, which dominus mentioned. Meaning the shop will be activated if player types q in chat, like typing Quebec. It doesn’t cause an error, but if you don’t want that behavior then check out the second argument of InputBegan- GameProcessedEvent, like colbert2677 did in their code. Anyway best of luck on your development!

1 Like

Thanks, I’ll be sure to check it out and experiment a bit.

1 Like