using UnityEngine; namespace BaseGames.Enemies { /// /// 推进停滞检测:滑动窗口内的**净水平位移**不足阈值即判为停滞。 /// 用于"命令了移动却推不动"的兜底(撞上未纳入检测层的碰撞体、贴墙微抖等)。 /// /// 用净位移而非逐帧差值,避免"贴墙推进-被弹回"的微抖每帧重置计数。 /// 调用方须以字段持有本结构(struct 的方法会就地修改字段); /// 开始移动 / 更换目标后调用 重开窗口。 /// public struct StallDetector { private readonly float _windowSeconds; private readonly float _minProgress; private float _timer; private float _startX; private bool _initialized; /// 判定窗口时长(秒)。 /// 窗口内所需的最小净位移(米)。 public StallDetector(float windowSeconds, float minProgress) { _windowSeconds = windowSeconds; _minProgress = minProgress; _timer = 0f; _startX = 0f; _initialized = false; } /// 以当前位置重开窗口。 public void Reset(float currentX) { _startX = currentX; _timer = 0f; _initialized = true; } /// /// 推进一帧。返回 true 表示本窗口内推进不足(停滞);返回 true 后窗口自动以当前位置重开。 /// public bool Tick(float currentX, float deltaTime) { if (!_initialized) { Reset(currentX); return false; } _timer += deltaTime; if (_timer < _windowSeconds) return false; bool stalled = Mathf.Abs(currentX - _startX) < _minProgress; _startX = currentX; _timer = 0f; return stalled; } } }