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; #if UNITY_EDITOR // ── 运行时调试(Inspector 中可见)─────────────────────────────── [Header("\u2500\u2500 \u8fd0\u884c\u65f6\u8c03\u8bd5 \u2500\u2500")] [SerializeField] private float _dbg_JumpBuffer; [SerializeField] private float _dbg_AttackBuffer; [SerializeField] private float _dbg_DashBuffer; #endif // ── 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); #if UNITY_EDITOR _dbg_JumpBuffer = _jumpBuffer; _dbg_AttackBuffer = _attackBuffer; _dbg_DashBuffer = _dashBuffer; #endif } /// 消耗跳跃缓冲(读取并清空)。 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; } } }