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

Unity新输入系统自定义热键如何避免重叠冲突问题

解决方案

方案1:全局缓存修饰键状态+位运算匹配(最低开销自定义实现)

你担心的性能问题完全不存在,常用修饰键总共只有8个,全局每帧只计算一次,开销可以忽略不计,实现逻辑如下:

  • 首先给带Flag标记的ModifierKeys枚举补充完整定义,可选增加左右修饰键的合并分组,适配不需要区分左右按键的场景:
[Flags]
public enum ModifierKeys
{
    None = 0,
    LeftCtrl = 1 << 0,
    RightCtrl = 1 << 1,
    LeftShift = 1 << 2,
    RightShift = 1 << 3,
    LeftAlt = 1 << 4,
    RightAlt = 1 << 5,
    LeftCmd = 1 << 6,
    RightCmd = 1 << 7,
    // 通用分组,不需要区分左右时使用
    Ctrl = LeftCtrl | RightCtrl,
    Shift = LeftShift | RightShift,
    Alt = LeftAlt | RightAlt,
    Cmd = LeftCmd | RightCmd
}
  • 优化Hotkey类,增加全局修饰键状态缓存,所有实例共用同一份缓存数据,每帧仅需要计算一次修饰键状态:
public class Hotkey
{
    // 全局缓存当前帧按下的所有修饰键组合
    private static ModifierKeys _currentFrameModifiers;
    
    // 全局更新方法,仅需要在游戏主循环的Update中调用一次
    public static void GlobalUpdateModifiers()
    {
        _currentFrameModifiers = ModifierKeys.None;
        var keyboard = Keyboard.current;
        if (keyboard == null) return;
        
        if (keyboard.leftCtrlKey.isPressed) _currentFrameModifiers |= ModifierKeys.LeftCtrl;
        if (keyboard.rightCtrlKey.isPressed) _currentFrameModifiers |= ModifierKeys.RightCtrl;
        if (keyboard.leftShiftKey.isPressed) _currentFrameModifiers |= ModifierKeys.LeftShift;
        if (keyboard.rightShiftKey.isPressed) _currentFrameModifiers |= ModifierKeys.RightShift;
        // Alt、Cmd按键同理补全判断逻辑即可
    }
    
    private readonly Key _mainKey;
    private readonly ModifierKeys _requiredModifiers;
    private readonly bool _allowGroupMatch;
    
    /// <param name="allowGroupMatch">是否允许同组修饰键匹配,比如按右Ctrl也触发LeftCtrl规则</param>
    public Hotkey(Key mainKey, ModifierKeys requiredModifiers, bool allowGroupMatch = true)
    {
        _mainKey = mainKey;
        _requiredModifiers = requiredModifiers;
        _allowGroupMatch = allowGroupMatch;
    }

    public bool isPressed
    {
        get
        {
            var keyboard = Keyboard.current;
            if (keyboard == null) return false;
            // 先判断主键是否按下
            if (!keyboard[_mainKey].isPressed) return false;
            // 修饰键精确匹配,排除多余修饰键
            if (_allowGroupMatch)
            {
                return (_currentFrameModifiers & _requiredModifiers) == _requiredModifiers 
                       && (_currentFrameModifiers & ~_requiredModifiers) == 0;
            }
            // 完全精确匹配,左右修饰键不互通
            return _currentFrameModifiers == _requiredModifiers;
        }
    }
}

方案2:直接使用Unity新输入系统原生功能(零自定义校验逻辑)

Unity新输入系统自带精确热键匹配能力,不需要自己实现校验逻辑:

  • 为每个热键创建独立的Input Action,绑定对应主键后添加需要的修饰键
  • 勾选修饰键配置中的*Exact Match*选项,系统会自动保证仅当没有额外修饰键按下时才触发该Action
  • 直接监听Action的performed事件或者每帧调用IsPressed()判断状态即可,原生实现性能最优,还自带跨平台适配。

内容的提问来源于stack exchange,提问作者user10972068

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:57:03