Problem with KeyCodes and keyboard layouts

I’m trying to make a custom keybind manager because unity does not have something to change keybinds in-game, and it’s almost working.
I’m using this code to catch the pressed keys:

	void OnGUI() {
		if(WaitingForKey) {
			if(Event.current.type == EventType.KeyDown) {
				KeyCode Key = Event.current.keyCode;
				if(Key != KeyCode.None) {
					BindKey(PendingBinding, Key);
					WaitingForKey = false;
					PendingBinding = -1;
					SetBindBox.gameObject.SetActive(false);
				}
			}
		}
	}

Now when I press i.e. Ü, the KeyCode will show up as Semicolon! Or when I press +, it shows up as Equals!
I assume this is because I have a german keyboard layout? Is there a way to make the correct KeyCodes show up for every keyboard layout?

Hi Zeblote!

In unity, the keycodes are defined in the KeyCode enum and can’t be changed unless you have the engine source. An alternative would be to use a different dll to read the keyboard, process the information, then map it to the Unity KeyCodes. They have the basic approach in this Unity Answers thread: http://answers.unity3d.com/questions/19114/keycodes-for-non-us-keyboard-layouts.html

Cheers!
Cahman

Well, how would I figure out what number each key represents?
Because I have no idea where he is getting that 219 from in the answers thread :c

If you use the code from the Answer page, you could have it print out every time you press a key.

Or, I think this table is accurate:
http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000520.html

Wait what

using UnityEngine;
using System.Collections;
 
using System.Runtime.InteropServices;
 
public class keyStateTester : MonoBehaviour {
 
    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    protected static extern short GetKeyState(int keyCode);
 
    public int GetEszett()
    {
        ushort i = (ushort)GetKeyState(219);
        return i;
    }
 
    // Update is called once per frame
    void Update ()
    {
        if(GetEszett() != 0)
            Debug.Log("Eszett has done something");
    }
}

^ The code from the answers thread

It tells me how I can check whether a specific key is pressed
It doesn’t tell me about an event for when a key is pressed

I meant something like the following, which prints out the keycode for a key when it is held down:

using UnityEngine;
using System.Collections;

using System.Runtime.InteropServices;

public class keytest : MonoBehaviour {
	
	[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    protected static extern short GetKeyState(int keyCode);
	
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
		
		//start at 3 to skip mouse buttons, 500 is a guess at uperbound, but seems to work
		for(int i = 3; i <500; i++)
		{
			//The options are:
			//0 if the key is neither down nor toggled,
			//-127 if the key is down but not toggled,
			//1 if the key is toggled but up, and
			//-128 if the key is both toggled and down.
			if(GetKeyState (i) == -127)
			{
				print (i);
			}
		}
		
	}
}

These pages may be helpful:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646301%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/ms927178.aspx

Cahman

Thanks!

Could this be more efficient though? GetKeyboardState function (winuser.h) - Win32 apps | Microsoft Learn

Scrap that, I cannot figure out how to use that function in my script

Well, how would I find out which key the number represents for the individual keyboard layout the user has?
I can’t tell the user he has bound “key 219”, I must tell him he has bound “ß” if he has a german layout or “[” if he has an american layout or whatever letter the key on his keyboard stands for, how do I get that information?

Inside of Unity, There isn’t anyway (at least not that I know of).

You could probably do it with one of the .NET/mono packages. KeyEventArgs might be what your looking for. However, I don’t think it’s included with Unity’s mono libraries. Here is a complete list of what’s included.

You could maybe load it as an external DLL (like user32.dll from above). But I think that would make it platform dependent (I doubt that library exists or works on a Linux box).

I would think there should be some easier way to do it, but I sure don’t know it if there is. Maybe someone else can chime in with some ideas.

Cahman

It doesn’t let me use System.Windows.Forms and I have no idea how to get it as an external resource :c

It was originally supposed to work on webplayer too, I started making the input manager because the default one doesn’t exist in webplayer, but this is getting way more complicated than I thought :u

Zeblote,

One Other thought I had: have you tried using event.character instead of event.keyCode? I don’t think it will work for things like the arrow keys of shift buttons, so you might need some combination of the two approaches.

I’m afraid I don’t know much about external resources. I think the Unity phrase is “Plugins.” But supposedly that won’t even work with the web player

I too made a custom input manager (the one in my signature) because there wasn’t one in the webplayer. But it just uses the KeyCode defined by Unity, so it will get the names wrong for non-US keyboards.

I tried to use the character but for the special keys (which are the problem here) the character is empty

I still have no solution for this. Any ideas?