Unity Windows Keyboard Hook Demo


化石原创文章,转载请注明来源并保留原文链接


因为一些需求,Unity窗口不能成为焦点,但是需要能知道键盘输入,还好是Windows版本,比较简单。不过中间也发生了点crash问题。所以把最后对应的代码放出来,供遇到问题的人参考,对比。

using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using UnityEngine.UI;
using System.Globalization;

public class KBHooks : MonoBehaviour
{
    [DllImport("user32.dll")]
    static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId);

    [DllImport("user32.dll")]
    static extern bool UnhookWindowsHookEx(IntPtr hInstance);

    [DllImport("user32.dll")]
    static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam);

    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibrary(string lpFileName);

    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

    const int WH_KEYBOARD_LL = 13;
    const int WM_KEYDOWN = 0x100;

    private LowLevelKeyboardProc _proc = hookProc;

    private static IntPtr hhook = IntPtr.Zero;

    public void SetHook()
    {
        IntPtr hInstance = LoadLibrary("User32");
        hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, hInstance, 0);
    }

    public void UnHook()
    {
        UnhookWindowsHookEx(hhook);
    }

    public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam)
    {
        if (code >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            if (vkCode.ToString() == "32")
            {
                text.text += "Space bar press.\n";
            }
        }
 
        return CallNextHookEx(hhook, code, (int)wParam, lParam);
    }


    static Text text;

	// Use this for initialization
	void Start()
	{
		Debug.Log("install hook");

		text = GameObject.Find ("Canvas/Text").GetComponent<Text>();
        SetHook();
	}

	void OnDisable()
	{
		Debug.Log("Uninstall hook");
        UnHook();
	}

}

这段代码里,测试按键是键盘的A,Unity场景中放了一个Text组件用于输出。代码在Unity 2019.1上测试。


化石原创文章,转载请注明来源并保留原文链接


1 评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注