using UnityEngine; namespace BaseGames.Input { /// /// 帧级输入缓冲。持续 _bufferDuration 秒,允许玩家提前输入跳跃/攻击/冲刺。 /// 须与 PlayerController 在同一 GameObject 上。 /// public class InputBuffer : MonoBehaviour { // _inputReader 由 PlayerController.Awake 注入,无需在 Inspector 单独配置。 private InputReaderSO _inputReader; [SerializeField] private float _jumpBufferDuration = 0.15f; [SerializeField] private float _attackBufferDuration = 0.12f; [SerializeField] private float _dashBufferDuration = 0.10f; private float _jumpBuffer; private float _attackBuffer; private float _dashBuffer; // ── Named handlers to allow proper unsubscription ───────────────────── private void HandleJumpStarted() => _jumpBuffer = _jumpBufferDuration; private void HandleAttackStarted() => _attackBuffer = _attackBufferDuration; private void HandleDashStarted() => _dashBuffer = _dashBufferDuration; /// 由 PlayerController 在 Awake 中注入 InputReader,无需在 Inspector 单独指定。 public void Init(InputReaderSO reader) { _inputReader = reader; } private void OnEnable() { if (_inputReader == null) return; _inputReader.JumpStartedEvent += HandleJumpStarted; _inputReader.AttackEvent += HandleAttackStarted; _inputReader.DashEvent += HandleDashStarted; } private void OnDisable() { if (_inputReader == null) return; _inputReader.JumpStartedEvent -= HandleJumpStarted; _inputReader.AttackEvent -= HandleAttackStarted; _inputReader.DashEvent -= HandleDashStarted; } private void Update() { float dt = Time.deltaTime; _jumpBuffer = Mathf.Max(0f, _jumpBuffer - dt); _attackBuffer = Mathf.Max(0f, _attackBuffer - dt); _dashBuffer = Mathf.Max(0f, _dashBuffer - dt); } /// 消耗跳跃缓冲(读取并清空)。 public bool ConsumeJump() { if (_jumpBuffer <= 0f) return false; _jumpBuffer = 0f; return true; } /// 消耗攻击缓冲(读取并清空)。 public bool ConsumeAttack() { if (_attackBuffer <= 0f) return false; _attackBuffer = 0f; return true; } /// 消耗冲刺缓冲(读取并清空)。 public bool ConsumeDash() { if (_dashBuffer <= 0f) return false; _dashBuffer = 0f; return true; } } }