美文网首页
Unity 按键拦截 以及修改输入按键 模拟按键输入 支持IL2

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

作者: 杰罗xr | 来源:发表于2019-01-18 09:56 被阅读0次

    本脚本作用 拦截原有按键 修改成另一个按键

    环境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);
    
        /// <summary>
        /// 
        /// 模拟按键按下抬起
        /// 
        /// keybd_event((byte)65, 0, 0, 0);   按下F10
        /// keybd_event((byte)65, 0, 2, 0);   按下后松开F10
        /// 
        /// </summary>
        /// <param name="bVk"></param>
        /// <param name="bScan"></param>
        /// <param name="dwFlags">0为按下 2为释放</param>
        /// <param name="dwExtraInfo"></param>
        [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

    相关文章

      网友评论

          本文标题:Unity 按键拦截 以及修改输入按键 模拟按键输入 支持IL2

          本文链接:https://www.haomeiwen.com/subject/kjugdqtx.html