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

Unity中罗技方向盘按钮单次按下多次触发问题修复

问题根因

问题确实出在Update生命周期的按钮检测逻辑,核心错误有三点:

  • LogitechGSDK.LogiButtonIsPressed 是持续按住状态检测接口,只要按钮保持按下,每帧调用都会返回true,行为和Unity原生Input.GetKey()一致,并非仅在按下瞬间返回一次的触发型接口。
  • 原有isReactionAlreadyGiven防重入标记完全失效:进入按钮处理分支后先将标记设为true,分支逻辑执行末尾立刻改回false,等于每帧都能重新触发分支逻辑,单次按按钮自然会多次执行数值增减。
  • 23号确认按钮的分支完全没加防重复触发逻辑,按住时会重复提交数值、重复调用ShowSlider。
修复方案
  • 新增三个按钮的上一帧状态缓存字段,通过「当前帧按下 + 上一帧未按下」的判断,实现按下瞬间仅触发一次逻辑,效果等价于Unity原生Input.GetKeyDown()。
  • 移除失效的同帧重置防重入标记逻辑,用帧状态对比天然实现防重复触发,不需要额外的布尔锁。
  • 把方向盘连接状态检测从每个按钮分支里抽出来,每帧只调用一次SDK接口检测,减少不必要的性能开销。
  • 所有按钮状态缓存在测试关闭、方向盘断开时统一重置,避免状态残留导致的触发异常。
具体代码修改

首先在类成员区域新增状态缓存字段:

// 缓存功能按钮上一帧按下状态,实现单次按下触发
private bool _prevBtn21Pressed = false;
private bool _prevBtn22Pressed = false;
private bool _prevBtn23Pressed = false;
private bool _wheelConnected = false;

替换原有Update方法逻辑:

private void Update()
{
    if (!ShouldFearTest)
    {
        _prevBtn21Pressed = false;
        _prevBtn22Pressed = false;
        _prevBtn23Pressed = false;
        return;
    }

    // 每帧仅检测一次方向盘连接状态
    _wheelConnected = LogitechGSDK.LogiIsConnected(0);
    if (!_wheelConnected)
    {
        _prevBtn21Pressed = false;
        _prevBtn22Pressed = false;
        _prevBtn23Pressed = false;
        return;
    }

    // 原有全按钮遍历逻辑保留
    for (int i = 0; i < 30; i++)
    {
        if (LogitechGSDK.LogiButtonIsPressed(0, i))
        {
            // 原有逻辑保留
        }
    }

    // 21号按钮:右拨 滑块数值+1
    bool currBtn21 = LogitechGSDK.LogiButtonIsPressed(0, 21);
    if (consoleFearTest.activeSelf && currBtn21 && !_prevBtn21Pressed)
    {
        int sliderValue = (int)slider.value;
        if (sliderValue < 9)
            sliderValue++;
        slider.value = sliderValue;
        Debug.Log("Fear Test valore impostato: " + sliderValue);
    }
    _prevBtn21Pressed = currBtn21;

    // 22号按钮:左拨 滑块数值-1
    bool currBtn22 = LogitechGSDK.LogiButtonIsPressed(0, 22);
    if (consoleFearTest.activeSelf && currBtn22 && !_prevBtn22Pressed)
    {
        int sliderValue = (int)slider.value;
        if (sliderValue > 0)
            sliderValue--;
        slider.value = sliderValue;
        Debug.Log("Fear Test valore impostato: " + sliderValue);
    }
    _prevBtn22Pressed = currBtn22;

    // 23号按钮:确认提交
    bool currBtn23 = LogitechGSDK.LogiButtonIsPressed(0, 23);
    if (consoleFearTest.activeSelf && currBtn23 && !_prevBtn23Pressed)
    {
        int sliderValue = (int)slider.value;
        Debug.Log("Fear Test : " + sliderValue);
        ShowSlider(false);
        fearTestValue.Add(sliderValue);
    }
    _prevBtn23Pressed = currBtn23;
}

在原有Reset()方法末尾追加状态重置逻辑:

_prevBtn21Pressed = false;
_prevBtn22Pressed = false;
_prevBtn23Pressed = false;
_wheelConnected = false;
可选优化
  • 如果需要实现按住按钮连续调整数值的交互,可以在检测到按钮持续按住超过300ms后,每隔100ms触发一次数值增减,匹配常规UI滑块的操作习惯。
  • 如果当前使用的罗技GSDK版本自带按钮按下瞬间触发的接口(部分版本命名为LogiButtonIsTriggered),可以直接替换自行实现的帧状态缓存逻辑,代码会更简洁。
  • 原有isReactionAlreadyGiven字段如果没有其他业务逻辑依赖,可以直接删除,帧状态对比已经完全覆盖防重复触发的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:24:12