You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
})();

问题分析与解决方案

核心问题

  1. Unity WebGL输入机制:这类游戏通常不依赖DOM键盘事件监听,而是直接读取键盘硬件状态,或者只识别标准的事件属性(而非已废弃的keyCode)。
  2. 单次事件无效:游戏需要持续的按键状态(按住A/D才会持续移动),单次keydown事件只会触发一次移动动作。
  3. 面板层级问题:原脚本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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 01:17:49