Expand Keys for UserInputService:GetStringForKeyCode

As a Roblox developer, it is currently too hard to display accurately display KeyCodes as strings.

I am currently displaying my project’s keybinds via UI to the player. I store player keybinds like:

["Toggle HUD"] = {
    ["Gamepad1"] = Enum.KeyCode.ButtonX,
    ["Keyboard"] = Enum.KeyCode.M,
},

I am then presenting the keybinds to the player using UserInputService:GetStringForKeyCode.
Documentation: UserInputService:GetStringForKeyCode

This should be the end of the story, but the function does not have an expansive KeyCode → string range, and comes up short. I am not trying to display complicated keybinds which require modifiers (ex: shift + P), just standard keys on a keyboard. For example, LeftShift (which is hugely popular as a keybind for runing) does not display (code snippet below) which is hugely problematic.

Code Snippet
local UserInputService = game:GetService("UserInputService")
local KeyCode = Enum.KeyCode.LeftShift
print(UserInputService:GetStringForKeyCode(KeyCode))

Output: empty string

If Roblox is able to address this issue, it would improve my development experience because I can provide greater clarity to players.

17 Likes

Why don’t you just do Enum.KeyCode.LeftShift.Name?

3 Likes

Roblox maps key codes on non-QWERTY keyboards to equivalent QWERTY positions. Printing the name property of a key codes works for QWERTY keyboards, but would be misleading to players without QWERTY keyboards (ex: French, Spanish, and German speaking countries). For the sake of thoroughness, I’d really like to use GetStringForKeyCode since it solves the problem by returning the equivalent key and is built into UserInputService, but it’s really limiting in its current form.

2 Likes

I use a roundabout method that converts a KeyCode Enum into a string, then substrings it to skip everything before the key’s name. I’ve never tested for non-QWERTY layouts, but would this work for you?

function GetStringForKeyCode(keyCode)
    keyCode = tostring(keyCode)
    keyCode = string.sub(keyCode, string.len("Enum.KeyCode._"))
    print(keyCode) -- Should print "LeftShift"
end

GetStringForKeyCode(Enum.KeyCode.LeftShift)
1 Like

It would solve the problem of GetStringForKeyCode not having enough Key → string pairings, but I don’t believe it would work for non QWERTY keyboards.

With that method, using Enum.KeyCode.Q on a QWERTY keyboard would correspond to a string of Q, but the same keycode on a non-QWERTY keyboard (ex: an AZERTY keyboard) would still correspond to a string of Q, although the actual key on the keyboard would be A.

Since Roblox remaps the keys to a QWERTY layout and there isn’t a way to detect the actual keyboard mapping, the info to the player would be misleading, which is why GetStringForKeyCode exists, although the number of Key → string pairings is too low (especially for common KeyCodes like LeftShift, LeftControl, etc.)

1 Like

I figured it would return the literal name and not the non-QWERTY alternative, but I’m offering it more as a backup method for when GetStringForKeyCode returns “”. For the time being, perhaps you could program for the QWERTY key names and offer different keyboard layout bindings (e.g. AZERTY remaps A to Q) in your game’s options.

Overall I would agree that GetStringForKeyCode should be more reliable so non-QWERTY compatibility isn’t a headache for developers nor players.

2 Likes

There is a Name property on EnumItems which can be used to get the name.

local key = Enum.KeyCode.LeftShift
print(key.Name) --> LeftShift
4 Likes

I know this is an old post but I am still going to reply with my solution to this for any new people who visits this post.

So, as we know the display on non-qwerty keyboards is different, and for KeyCodes like “LeftShift” this super useful method of UserInputService returns an empty string.

My idea now is to use this method, but also combine it with the “unsafe” KeyCodes.Name since there are many KeyCodes which still would work on both qwerty and non-qwerty.

local UserInputService = game:GetService("UserInputService")
local KeyCode = Enum.KeyCode.LeftShift

local function CustomGetStringForKeyCode(KeyCode: Enum.KeyCode): string
      local str = UserInputService:GetStringForKeyCode(KeyCode)
      return if str ~= "" then str else KeyCode.Name
end

print(CustomGetStringForKeyCode(KeyCode)) -- Output: "LeftShift"