How to Detect the Currently Pressed Key

How to detect the currently pressed key?

if ((Control.ModifierKeys & Keys.Shift) != 0) 

This will also be true if Ctrl+Shift is down. If you want to check whether Shift alone is pressed,

if (Control.ModifierKeys == Keys.Shift)

If you're in a class that inherits Control (such as a form), you can remove the Control.

How to find out what character key is pressed?

"Clear" JavaScript:

function myKeyPress(e){
var keynum;

if(window.event) { // IE
keynum = e.keyCode;
} else if(e.which){ // Netscape/Firefox/Opera
keynum = e.which;
}

alert(String.fromCharCode(keynum));
}
<input type="text" onkeypress="return myKeyPress(event)" />

How to detect if any key is pressed

public static IEnumerable<Key> KeysDown()
{
foreach (Key key in Enum.GetValues(typeof(Key)))
{
if (Keyboard.IsKeyDown(key))
yield return key;
}
}

you could then do:

if(KeysDown().Any()) //...

Get a list of all currently pressed keys in Javascript

  • whenever a key is pressed a keydown event will be sent
  • whenever a key is released a keyup event will be triggered

So you just need to save the keys in an array and check whether your combination is true.

Example

var keys = [];
window.addEventListener("keydown",
function(e){
keys[e.keyCode] = true;
checkCombinations(e);
},
false);

window.addEventListener('keyup',
function(e){
keys[e.keyCode] = false;
},
false);

function checkCombinations(e){
if(keys["a".charCodeAt(0)] && e.ctrlKey){
alert("You're not allowed to mark all content!");
e.preventDefault();
}
}

Note that you should use e.key instead of e.keyCode whenever possible (in this case var key = {}, since e.key is a string).

Detect all the Key Pressed in keyboard

If you want to find which keys are pressed, you could do this,

     if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) // Is Alt key pressed
{
if (Keyboard.IsKeyDown(Key.LeftCtrl) && Keyboard.IsKeyDown(Key.A))
{
MessageBox.Show("Key pressed");
}
}

Get currently pressed keys in inspector

Depends a lot on how you store and check the hotkeys later but you could create a custom EditorWindow pop-up.

First I would store my shortcut e.g. like

[Serializable]
public struct ShortCut
{
public bool Ctrl;
public bool Alt;
public bool Shift;

public KeyCode Key;

public ShortCut(KeyCode key, bool ctrl, bool alt, bool shift)
{
Key = key;
Ctrl = ctrl;
Alt = alt;
Shift = shift;
}

public override string ToString()
{
var builder = new StringBuilder();
if (Ctrl) builder.Append("CTRL + ");
if (Alt) builder.Append("ALT + ");
if (Shift) builder.Append("SHIFT + ");

builder.Append(Key.ToString());

return builder.ToString();
}

public bool IsDown => IsCtrlDown && IsAltDown && IsShiftDown && Input.GetKeyDown(Key);

private bool IsCtrlDown => !Ctrl || Input.GetKey(KeyCode.RightControl) || Input.GetKey(KeyCode.LeftControl);
private bool IsAltDown => !Alt || Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);
private bool IsShiftDown => !Shift || Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
}

You can wait for it in a script like e.g.

public class ShortCutTester : MonoBehaviour
{
// This youc an now call via the context menu of the someShortCut field in the Inspector
[ContextMenuItem("Set Shortcut", nameof(SetSomeShortCut))]
public ShortCut someShortCut;

private void SetSomeShortCut()
{
ShortKeyDialog.ShowDialog(someShortCut, result =>
{
// mark as dirty and provide undo/redo funcztionality
Undo.RecordObject(this, "Change someShortCut");
someShortCut = result;
});
}

private void Update()
{
if (someShortCut.IsDown)
{
Debug.Log("Hello!");
}
}

#if UNITY_EDITOR
// in order to catch all editor own key events on runtime
// you will still get the warning "You have to exit playmode in order to save"
// but at least this makes the Hello print anyway. Couldn't figure out how to catch the key completely before Unity handles it
private void OnGUI()
{
var e = Event.current;
e.Use();
}
#endif
}

and set it via a popup dialog

public class ShortKeyDialog : EditorWindow
{
private ShortCut keys;
private ShortCut newKeys;
private Action<ShortCut> callback;
private bool changed;

public static void ShowDialog( ShortCut currentShortcut, Action<ShortCut> onDone)
{
var dialog = GetWindow<ShortKeyDialog>();
dialog.keys = currentShortcut;
dialog.newKeys = currentShortcut;
dialog.callback = onDone;
dialog.minSize = new Vector2(300, 200);
dialog.position = new Rect(Screen.width / 2f + 150, Screen.height / 2f + 100, 300, 200);
dialog.ShowModalUtility();
}

private void OnGUI()
{
//Get pressed keys
var e = Event.current;
if (e?.isKey == true)
{
switch (e.type)
{
case EventType.KeyDown:
switch (e.keyCode)
{
// Here you will need all allowed keycodes
case KeyCode.A:
case KeyCode.B:
case KeyCode.C:
case KeyCode.D:
case KeyCode.E:
case KeyCode.F:
case KeyCode.G:
case KeyCode.H:
case KeyCode.I:
case KeyCode.J:
case KeyCode.K:
case KeyCode.L:
case KeyCode.M:
case KeyCode.N:
case KeyCode.O:
case KeyCode.P:
case KeyCode.Q:
case KeyCode.R:
case KeyCode.S:
case KeyCode.T:
case KeyCode.U:
case KeyCode.V:
case KeyCode.W:
case KeyCode.X:
case KeyCode.Y:
case KeyCode.Z:
case KeyCode.F1:
case KeyCode.F2:
case KeyCode.F3:
case KeyCode.F4:
case KeyCode.F5:
case KeyCode.F6:
case KeyCode.F7:
case KeyCode.F8:
case KeyCode.F9:
case KeyCode.F10:
case KeyCode.F11:
case KeyCode.F12:
case KeyCode.F13:
case KeyCode.F14:
case KeyCode.F15:
case KeyCode.Comma:
case KeyCode.Plus:
case KeyCode.Minus:
case KeyCode.Period:
// etc depends on your needs I guess
changed = true;
newKeys = new ShortCut (e.keyCode, e.control, e.alt, e.shift);

// Refresh the EditorWindow
Repaint();
break;
}
break;
}

// Use all key presses so nothing else handles them
// e.g. also not the Unity editor itself like e.g. for CTRL + S
e.Use();
}

EditorGUILayout.LabelField("Current Shortcut");
EditorGUILayout.HelpBox(keys.ToString(), MessageType.None);

EditorGUILayout.Space();

EditorGUILayout.LabelField("Press buttons to assign a new shortcut", EditorStyles.textArea);

EditorGUILayout.HelpBox(newKeys.ToString(), MessageType.None);

EditorGUILayout.Space();

EditorGUILayout.BeginHorizontal();
{
if (GUILayout.Button("Cancel"))
{
Close();
}
EditorGUI.BeginDisabledGroup(!changed);
{
if (GUILayout.Button("Save"))
{
callback?.Invoke(newKeys);
Close();
}
}
EditorGUI.EndDisabledGroup();
}
EditorGUILayout.EndHorizontal();
}
}

Please note: Typed on smartphone so no chance to test and correct things currently but I hope the idea gets clear

Will test and update asap when back on a PC

Python 3 pressed key detect

I got some answer, i don't know all imported libraries are builtin python or not, but it worked perfectly

#!/usr/bin/python3

# adapted from https://github.com/recantha/EduKit3-RC-Keyboard/blob/master/rc_keyboard.py

import sys, termios, tty, os, time

def getch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)

finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch

button_delay = 0.2

while True:
char = getch()

if (char == "p"):
print("Stop!")
exit(0)

if (char == "a"):
print("Left pressed")
time.sleep(button_delay)

elif (char == "d"):
print("Right pressed")
time.sleep(button_delay)

elif (char == "w"):
print("Up pressed")
time.sleep(button_delay)

elif (char == "s"):
print("Down pressed")
time.sleep(button_delay)

elif (char == "1"):
print("Number 1 pressed")
time.sleep(button_delay)

Is there a way to detect if a key has been pressed?

I use the following function for kbhit(). It works fine on g++ compiler in Ubuntu.

#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
int kbhit(void)
{
struct termios oldt, newt;
int ch;
int oldf;

tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

ch = getchar();

tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);

if(ch != EOF)
{
ungetc(ch, stdin);
return 1;
}

return 0;
}


Related Topics



Leave a reply



Submit