Godot Version
4.2.2
Question
Hi, I am making a typing game where I have a virtual keyboard on the screen. I’m trying to map the in-game keyboard to the keyboard of the user.
I’ve tested out OS.get_keycode_string(event.get_physical_keycode_with_modifiers()). and that gives me a string with the keys like “A” or “shift+A”. I am looking for a way to convert “shift+A” to “a”. I also want this to work with all keyboard layouts. I also want this to work with keys like “shift+period” that on some layout is “>” and on others is “:”. I can get the right keys when using a text edit box but that requires the player to type in the letters before i can update my in-game keyboard.
I think you should be able to just write OS.get_keycode_string(event.physical_keycode)
.
1 Like
OS.get_keycode_string(event.physical_keycode) returns “A” if shift is pressed or not.
I want to do something like this:
for ph_keycode in allKeysOnKeyboard:
var primary = OS.get_keycode_string(ph_keycode )
var secoundar = OS.?????(ph_keycode , ShiftIsPressed==true)
print("if you press: ", ph_keycode, " you will type ", primary, "or ", secoundary, "if
you hold shift while pressing")
#return
"if you press 65 you get a or A if you hold shift while pressing
if you press 46 you get . or > if you hold shift while pressing
......"
Hmm. For that you need information on the layout contents. I’m not sure if Godot has that somewhere, maybe in the virtual keyboard implementation.
One hacky idea I had is that you could create a LineEdit, feed it an InputEvent with the key and shift pressed, and see what the LineEdit’s text reads.
Yes I Do need information from the layout. Get_keycode_to_string() need some of this information to be able to work with no shift keys. I was hoping there would be a function with the second half of the information I haven’t found yet.
How can I feed inputEvents to lineEdits?
I’ve never tried it myself, but there’s Input.parse_input_event(event)
which sends an input event to the game. Unfortunately it’s for the entire game, and I don’t think it can be targeted at the LineEdit.
I’m not sure if there’s a practical way to do that. If you wanted to get hacky you could set focus to the LineEdit, call that function and then put the focus back, hopefully before the user has time to act. But it might break if they press a key at the wrong time.
Maybe that could be done right after loading, before the game is shown/enabled. But you’d still need to check if the event is the one you sent.
We used the keycode directly, but it doesn’t handle the shift modifier on it’s own.
This bitwise trick will work for ASCII letters, not sure for all other languages/unicode, doesn’t work for special characters.
func _input(event: InputEvent) -> void:
if event is InputEventKey:
var unicode: int
if not event.shift_pressed:
unicode = event.keycode | 0x20
else:
unicode = event.keycode
if unicode > 20 and unicode < 40_000: # filters most control characters
var letter := String.chr(unicode)
print(letter)