Files
zeling_v2/Assets/_Game/Scripts/World/BreadcrumbTracker.cs

71 lines
2.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using BaseGames.Core.Events;
using UnityEngine;
namespace BaseGames.World
{
/// <summary>
/// 玩家面包屑轨迹追踪器(架构 21_LiquidPuzzleModule §15
/// 每 RecordInterval 秒记录一次玩家位置(仅当移动距离超过 MinMoveDistance 时)。
/// 最多保存 MaxCrumbs 个历史位置,超出后移除最旧的。
/// </summary>
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<Vector2> _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 ──────────────────────────────────────────────────────
/// <summary>返回最近 count 个面包屑位置(从旧到新排列)。</summary>
public IReadOnlyList<Vector2> GetRecentCrumbs(int count)
{
var result = new List<Vector2>(_crumbs);
if (result.Count <= count) return result;
return result.GetRange(result.Count - count, count);
}
/// <summary>清空全部轨迹记录(如死亡后重生时调用)。</summary>
public void Clear() => _crumbs.Clear();
}
}