How to detect which key is pressed?

I am trying to determine which Keyboard key is pressed to use that in a switch statement, but apparently the code I try to use is not working. It was taken more or less directly from the Script Reference, but ‘Event.current’ doesn’t seem to detect my keyboard strokes. When I print it to the status bar, it says ‘Null’.

var pressKey;
var dirEvent : Event = Event.current;
if(dirEvent.isKey) {
	pressKey = dirEvent.keyCode;
}

foreach(KeyCode vKey in System.Enum.GetValues(typeof(KeyCode))){
if(Input.GetKey(vKey)){
//your code here

			}
		}

:slight_smile: this detects what key has been pressed.
I use it for my custom input manaer.

The following code worked for me. It is based of of @jamesflowerdew. Firstly a KeyCode variable is created. This variable would store the custom key press. The DetectInput() function captures the key input by the user and stores it in kCode. kCode is then used in the Input.GetKeyDown(KeyCode) function. With this approach you should be able to create an array or a series of KeyCode variables that have specified functions and theese KeyCode variables can be changed to any input key the user wants.

So you will be able to create a

  • KeyCode jumpKCode
  • jumpKCode can be used in the following for you jump trigger
  • if( Input.GetKeyDown(jumpKCode))
  • {
  •           Jump();
    
  • }

jumpKCode can be assign any key input. Hopefully this makes sense to anyone who is struggling with this.

private bool bDetectKey;
    private KeyCode kCode;  //this stores your custom key
	
	void Update ()
    {
        if(Input.GetKeyDown(KeyCode.Return))
        {
            if (bDetectKey)
                bDetectKey = false;
            else
                bDetectKey = true;
        }

        if(bDetectKey)  //this detects the key being pressed and saves it to kCode
            DetectInput();   

        if(Input.GetKeyDown(kCode)) //the kCode is then compared like a standard Input.GetKeyDown(KeyCode) boolean
        {
            print("Custom key worked");
        }        
	}

    public void DetectInput()
    {
        foreach(KeyCode vkey in System.Enum.GetValues(typeof(KeyCode)))
        {
            if(Input.GetKey(vkey))
            {
                if (vkey != KeyCode.Return)
                {
                    kCode = vkey; //this saves the key being pressed               
                    bDetectKey = false;
                }
            }
        }
    }

Your question doesn’t give too much information, but here are a few options:

If you are absolutely tied to using a switch statement to iterate through your keys, you could do something like this:

var myKeys : Array;

function Start() {
	myKeys = new Array();
	myKeys.Add(KeyCode.W);
	myKeys.Add(KeyCode.S);
	myKeys.Add(KeyCode.A);
	myKeys.Add(KeyCode.D);
}

function Update () {

	for (var key : KeyCode in myKeys)
	{
		if (Input.GetKeyDown(key))
		{
			switch (key)
			{
				case KeyCode.W: 
					Debug.Log("W!");
					break;
				case KeyCode.S:
					Debug.Log("S!");
					break;
				case KeyCode.A:
					Debug.Log("A!");
					break;
				case KeyCode.D:
					Debug.Log("D!");
					break;
			}
		}
	}
}

However, it would probably be slightly cleaner if you did this:

if (Input.GetKeyDown(KeyCode.W))
{
}

if (Input.GetKeyDown(KeyCode.S))
{
}

if (Input.GetKeyDown(KeyCode.A))
{
}

if (Input.GetKeyDown(KeyCode.D))
{
}

Change the consecutive "if"s to “else if” if you only want one input to work at a time. Change “GetKeyDown” to “GetKey”, if you want it to recognize the input every frame.

You can avoid using many ifs, but you can’t avoid using Input.GetKey(Down). The trick is the following: switch(argument) compares the argument to each case. By using true as the argument, you can use boolean statements as cases:

switch(true) {
  case Input.GetKey("g"):
    statics.plHeading = Vector2(1,0);
    break;

  case Input.GetKey("d"):
    // and so on...
  
  default:
    // this way, you can still use a default statement
}

The method described from Scenia does not work for me. The compiler says, that after the “case”-statement has to be a constant value.

However I thought it would be nice having a dictionary with the button name as key and the function to call as value:

using System.Collections.Generic;
using UnityEngine;

private Dictionary<string, InputDelegate> myKeys;
private delegate void InputDelegate();
private InputDelegate myTempDelegate;

private void start()
{
	this.myKeys = new Dictionary<string, InputDelegate> ();

	this.myTempDelegate = Fire;
	myKeys.Add ("Fire1",myTempDelegate);

	this.myTempDelegate = Inventory;
	myKeys.Add ("Inventory",myTempDelegate);
}

private Update()
{
	if (Input.anyKeyDown)
	{
		foreach (var dic in this.myKeys)
		{
			if (Input.GetButtonDown (dic.Key))
			{
				dic.Value ();
			}
		}
	}
}

private void Fire()
{
	//do all the stuff to fire
}

private void Inventory()
{
	//open up the inventory
}

You would need to specify a key for the button “inventory” in the input manager, since it is not there by default.
This way, you keep your update method short and tidy, but get the key-function-binding section in the start method, which could get long, if you are having many keys.
For general movement of a character you should do something like this:

 private void FixedUpdate()
    {
          // read inputs
    	float h = Input.GetAxis ("Horizontal");
    	float v = CrossPlatformInputManager.GetAxis("Vertical");
    	bool crouch = Input.GetKey(KeyCode.C);
    
    	//do all the physics stuff...
    	//...
    }

Anyway… I guess in terms of performance you could / (should?) stick with the method of having all the if (Input.GetKeyDown(…)) 's in the update method.

You should wrap that in an any key so it runs only when a key is pressed.

You need to call the OGUI function of monobehaviour。
public class Test : MonoBehaviour { private void OnGUI() { if (Event.current.isKey) { Debug.Log(Event.current.keyCode); } } }

@Piflik

var c = Input.inputString;
if (c!=“”) {
Debug.Log(c);
}