Tampermonkey脚本勾选复选框后无法移动游戏角色问题排查
问题:模拟A/D按键无法驱动Erz Online游戏角色移动
我用Tampermonkey给https://app.erz.online/写了个脚本,想实现勾选复选框时模拟A、D按键让游戏角色移动,但角色完全没反应。试过给document触发键盘事件、改用左箭头键码都没用,不知道问题出在哪。
原脚本代码
// ==UserScript== // @name Erz Online Energy Pump // @namespace https://app.erz.online/ // @version 1 // @description Adds a panel to the lower right corner of the screen on https://app.erz.online/ with a checkbox labeled 'pumping energy' that activates pressing the 'A' and 'D' keys to move in the game. // @match https://app.erz.online/* // @grant none // ==/UserScript== (function() { 'use strict'; const panel = document.createElement('div'); panel.style.position = 'fixed'; panel.style.bottom = '100px'; panel.style.right = '0'; panel.style.width = '200px'; panel.style.height = '100px'; panel.style.backgroundColor = '#262626'; panel.style.borderRadius = '5px'; panel.style.padding = '10px'; panel.style.boxShadow = '2px 2px 5px rgba(0, 0, 0, 0.3)'; panel.style.zIndex = '0'; const checkbox1 = document.createElement('input'); checkbox1.type = 'checkbox'; checkbox1.id = 'pumping-energy'; checkbox1.style.marginRight = '10px'; const label1 = document.createElement('label'); label1.htmlFor = 'pumping-energy'; label1.style.color = "#ffffff"; label1.innerText = 'Pumping Energy'; panel.appendChild(checkbox1); panel.appendChild(label1); document.body.appendChild(panel); checkbox1.addEventListener('change', function() { if (this.checked) { console.log("on"); var canvas = document.getElementById('unity-canvas'); simulateKeyPress(canvas, 65); } else { console.log("off"); } }); function simulateKeyPress(canvas, keyCode) { var keyboardEvent = new KeyboardEvent('keydown', { keyCode: keyCode }); console.log(keyboardEvent) canvas.dispatchEvent(keyboardEvent); } })();
问题分析与解决方案
核心问题
- Unity WebGL输入机制:这类游戏通常不依赖DOM键盘事件监听,而是直接读取键盘硬件状态,或者只识别标准的事件属性(而非已废弃的
keyCode)。 - 单次事件无效:游戏需要持续的按键状态(按住A/D才会持续移动),单次
keydown事件只会触发一次移动动作。 - 面板层级问题:原脚本
z-index=0,可能被Unity Canvas遮挡,导致复选框交互异常(虽你提到能触发change,但仍需优化)。
修改后的脚本
// ==UserScript== // @name Erz Online Energy Pump // @namespace https://app.erz.online/ // @version 2 // @description 给Erz Online添加自动移动面板,勾选后循环模拟A/D按键驱动角色移动 // @match https://app.erz.online/* // @grant none // ==/UserScript== (function() { 'use strict'; const panel = document.createElement('div'); panel.style.position = 'fixed'; panel.style.bottom = '100px'; panel.style.right = '0'; panel.style.width = '200px'; panel.style.height = '100px'; panel.style.backgroundColor = '#262626'; panel.style.borderRadius = '5px'; panel.style.padding = '10px'; panel.style.boxShadow = '2px 2px 5px rgba(0, 0, 0, 0.3)'; panel.style.zIndex = '9999'; // 提高层级确保面板不被遮挡 const checkbox1 = document.createElement('input'); checkbox1.type = 'checkbox'; checkbox1.id = 'pumping-energy'; checkbox1.style.marginRight = '10px'; const label1 = document.createElement('label'); label1.htmlFor = 'pumping-energy'; label1.style.color = "#ffffff"; label1.innerText = '自动移动(A/D循环)'; panel.appendChild(checkbox1); panel.appendChild(label1); document.body.appendChild(panel); let moveInterval = null; let currentKey = 'KeyA'; checkbox1.addEventListener('change', function() { if (this.checked) { console.log("开始自动移动"); // 循环切换A/D,模拟持续移动 moveInterval = setInterval(() => { simulateKeyPress(currentKey); currentKey = currentKey === 'KeyA' ? 'KeyD' : 'KeyA'; }, 500); } else { console.log("停止自动移动"); clearInterval(moveInterval); // 发送keyup重置按键状态 simulateKeyPress('KeyA', 'keyup'); simulateKeyPress('KeyD', 'keyup'); } }); function simulateKeyPress(code, eventType = 'keydown') { const target = document.getElementById('unity-canvas') || document; const event = new KeyboardEvent(eventType, { key: code === 'KeyA' ? 'a' : 'd', code: code, bubbles: true, cancelable: true, view: window }); target.dispatchEvent(event); console.log(`触发${eventType}事件:${code}`); } })();
关键修改点
- 提高面板层级:把
z-index设为9999,确保面板在游戏Canvas上方,能正常点击交互。 - 持续循环模拟:用
setInterval循环触发A/D的keydown事件,模拟按住按键的持续移动效果。 - 标准化事件参数:使用标准的
code和key属性替代已废弃的keyCode,同时设置bubbles: true让事件能正确冒泡,适配Unity的输入监听逻辑。 - 停止时重置状态:取消勾选时发送
keyup事件,避免游戏认为按键仍处于按下状态。
额外排查方向
如果修改后还是无效,可能是Unity直接读取键盘硬件状态,DOM事件模拟无法触发。这种情况下可以尝试:
- 使用Tampermonkey的特权函数
GM_sendKeyEvent(需要修改@grant GM_sendKeyEvent) - 检查游戏Canvas的事件监听器,确认输入绑定的目标元素
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

