using System.Collections.Generic; using BaseGames.Core.Events; using UnityEngine; namespace BaseGames.World { /// /// 玩家面包屑轨迹追踪器(架构 21_LiquidPuzzleModule §15)。 /// 每 RecordInterval 秒记录一次玩家位置(仅当移动距离超过 MinMoveDistance 时)。 /// 最多保存 MaxCrumbs 个历史位置,超出后移除最旧的。 /// public class BreadcrumbTracker : MonoBehaviour { [SerializeField, Min(0.1f)] private float _recordInterval = 2f; [SerializeField, Min(1)] private int _maxCrumbs = 20; [SerializeField, Min(0.1f)] private float _minMoveDistance = 1f; [Header("事件频道")] [SerializeField] private TransformEventChannelSO _onPlayerSpawned; private readonly Queue _crumbs = new(); private readonly CompositeDisposable _subs = new(); private Vector2 _lastPos; private float _timer; private Transform _playerTransform; // ── Unity 生命周期 ──────────────────────────────────────────────── private void OnEnable() { _onPlayerSpawned?.Subscribe(t => _playerTransform = t).AddTo(_subs); } private void OnDisable() { _subs.Clear(); } private void Update() { if (_playerTransform == null) return; _timer += Time.deltaTime; if (_timer < _recordInterval) return; _timer = 0f; Vector2 pos = _playerTransform.position; if (_crumbs.Count > 0 && Vector2.Distance(pos, _lastPos) < _minMoveDistance) return; _crumbs.Enqueue(pos); _lastPos = pos; while (_crumbs.Count > _maxCrumbs) _crumbs.Dequeue(); } // ── 公共 API ────────────────────────────────────────────────────── /// 返回最近 count 个面包屑位置(从旧到新排列)。 public IReadOnlyList GetRecentCrumbs(int count) { var result = new List(_crumbs); if (result.Count <= count) return result; return result.GetRange(result.Count - count, count); } /// 清空全部轨迹记录(如死亡后重生时调用)。 public void Clear() => _crumbs.Clear(); } }