Unity 按键拦截 以及修改输入按键 模拟按键输入 支持IL2CPP

键盘钩子

环境win10 打包参数 IL2CPP 2018.2.0f2 Windows X86 .NET 4.x

放到Unity里注意当unity失去焦点时 应取消键盘钩子 否则在程序外也会生效

using UnityEngine;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;


public class MonoPInvokeCallbackAttribute : Attribute
{
    public MonoPInvokeCallbackAttribute() { }
}

public class WindowsKeyTool : MonoBehaviour
{
    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;
    private static LowLevelKeyboardProc _proc = HookCallback;
    private static int _hookID;
    public static bool KeyOn = true;

    void Start()
    {
        UnhookWindowsHookEx((IntPtr)_hookID);
        _hookID = SetHook(_proc);
    }


    void OnApplicationQuit()
    {
        UnhookWindowsHookEx((IntPtr)_hookID);
    }

    private void OnDestroy()
    {
        UnhookWindowsHookEx((IntPtr)_hookID);
    }

    private static int SetHook(LowLevelKeyboardProc proc)
    {
        return SetWindowsHookEx(WH_KEYBOARD_LL, proc, IntPtr.Zero, 0);
    }

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

    //return 1 代表拦截  
    [MonoPInvokeCallback]
    private static int HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        //wParam == 256 代表 按下操作 257 代表抬起操作
        int vkCode = Marshal.ReadInt32(lParam);
        bool isKeyDown = ((int)wParam == WM_KEYDOWN);

        if (vkCode == 0x41)//如果按下A 截断 重新按下 新的按键
        {
            if (isKeyDown)
            {
                keybd_event(91, 0, 0, 0); 
                return 1;
            }
            else
            {
                keybd_event(91, 0, 2, 0); 
                return 1;
            }
        }
        return CallNextHookEx((IntPtr)_hookID, nCode, wParam, lParam);//不拦截将按键消息传递给下个钩子
    }



    [DllImport("user32.dll")]   // 注意下面这三个函数和其他网上找到的 不一样 我把一些 IntPtr 参数以及返回值 改成了 int  (不改  编辑器以及mono打包是没问题的)
                                //不改的话 il2cpp 会说参数C错误  不知道为什么 希望知道的大神告知 学习学习
    private static extern int SetWindowsHookEx(int idHook,LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

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

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

    /// 
    /// 
    /// 模拟按键按下抬起
    /// 
    /// keybd_event((byte)65, 0, 0, 0);   按下F10
    /// keybd_event((byte)65, 0, 2, 0);   按下后松开F10
    /// 
    /// 
    /// 
    /// 
    /// 0为按下 2为释放
    /// 
    [DllImport("user32.dll")]
    public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
}


键值表 https://blog.csdn.net/tonykk2008/article/details/8264967
不支持Unity2021

你可能感兴趣的:(Unity 按键拦截 以及修改输入按键 模拟按键输入 支持IL2CPP)