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

如何在C#类的Update方法中为布尔开关实现低通滤波器?

给布尔值实现低通滤波(过滤快速状态切换)

我懂你遇到的问题——之前用在加速度计上的低通类是针对连续数值的,但布尔值是离散的二值信号,直接套用肯定不合适。在Unity的Update/FixedUpdate里过滤布尔值的快速切换,本质是要实现「防抖」或者「状态平滑认可」,下面给你两种实用的实现思路:

方法一:时间阈值防抖(最直观的过滤方式)

这种方式的核心是:只有当状态保持稳定超过设定的时间阈值,才认可这次状态切换,直接过滤掉短时间内的反复跳动。

代码示例

using UnityEngine;

public class BooleanDebounce : MonoBehaviour
{
    // 你的原始布尔输入
    public bool myBoolean;
    
    private bool _currentValidState;
    private float _lastStateChangeTime;
    // 调整这个值控制过滤灵敏度(单位:秒),值越大过滤越严格
    [SerializeField] private float _debounceThreshold = 0.2f;

    void Update()
    {
        bool rawInput = myBoolean;

        // 只有当原始输入和当前有效状态不一致时,才进入判断逻辑
        if (rawInput != _currentValidState)
        {
            // 检查距离上次状态切换是否已经过了阈值时间
            if (Time.time - _lastStateChangeTime >= _debounceThreshold)
            {
                // 更新有效状态,并记录当前时间
                _currentValidState = rawInput;
                _lastStateChangeTime = Time.time;
                
                // 这里写状态真正变化后的业务逻辑
                OnValidStateSwitched(_currentValidState);
            }
            // 否则直接忽略这次快速切换
        }
    }

    // 状态有效切换时的回调(可根据需求修改)
    private void OnValidStateSwitched(bool newState)
    {
        Debug.Log($"布尔状态已稳定切换为:{newState}");
    }

    // 初始化初始状态
    void Start()
    {
        _currentValidState = myBoolean;
        _lastStateChangeTime = Time.time;
    }
}

方法二:模拟低通滤波的状态平滑

如果你更想贴合「低通滤波」的概念,可以把布尔值转成连续的浮点值,再用类似加速度计的平滑逻辑处理,最后通过阈值判断来切换有效状态。

代码示例

using UnityEngine;

public class BooleanLowPass : MonoBehaviour
{
    public bool myBoolean;
    
    private bool _currentValidState;
    // 平滑系数(0~1):值越小,过滤效果越强(越难切换状态)
    [SerializeField] private float _smoothFactor = 0.1f;
    private float _smoothValue;

    void FixedUpdate()
    {
        bool rawInput = myBoolean;
        // 将布尔值转为0(false)或1(true)的连续数值
        float target = rawInput ? 1f : 0f;

        // 应用低通滤波公式(和加速度计的平滑逻辑类似)
        _smoothValue = Mathf.Lerp(_smoothValue, target, _smoothFactor);

        // 当平滑值超过0.5时判定为true,低于则为false
        bool newValidState = _smoothValue >= 0.5f;
        if (newValidState != _currentValidState)
        {
            _currentValidState = newValidState;
            OnValidStateSwitched(_currentValidState);
        }
    }

    private void OnValidStateSwitched(bool newState)
    {
        Debug.Log($"经过平滑后的布尔状态:{newState}");
    }

    void Start()
    {
        _currentValidState = myBoolean;
        _smoothValue = myBoolean ? 1f : 0f;
    }
}

额外注意点

  • 如果用FixedUpdate,建议把_smoothFactor和Time.fixedDeltaTime结合(比如_smoothFactor * Time.fixedDeltaTime),避免帧率波动影响平滑效果。
  • 两种方法可以根据需求选择:防抖适合需要「明确稳定状态」的场景(比如按钮触发);平滑滤波适合需要「抗干扰渐进式认可」的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:11:15