如何在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
相关产品推荐
相关产品推荐

