diff --git a/Assets/_Game/Scripts/Enemies/Navigation/FlyingDirectNavigator.cs b/Assets/_Game/Scripts/Enemies/Navigation/FlyingNavigator.cs
similarity index 53%
rename from Assets/_Game/Scripts/Enemies/Navigation/FlyingDirectNavigator.cs
rename to Assets/_Game/Scripts/Enemies/Navigation/FlyingNavigator.cs
index ba2be3b6..4f407c6c 100644
--- a/Assets/_Game/Scripts/Enemies/Navigation/FlyingDirectNavigator.cs
+++ b/Assets/_Game/Scripts/Enemies/Navigation/FlyingNavigator.cs
@@ -1,25 +1,23 @@
-using System;
using UnityEngine;
using BaseGames.Enemies;
namespace BaseGames.Enemies.Navigation
{
///
- /// 飞行单位直线导航代理。
- /// 不依赖 PathBerserker2d 寻路,直接通过 Rigidbody2D.MovePosition 向目标点直飞。
+ /// 飞行单位直线导航代理,实现 。
+ /// 不依赖寻路网格,直接通过 Rigidbody2D.MovePosition 向目标点直飞。
///
/// 特性:
///
/// - 空闲时施加正弦波形悬停偏移,产生飘浮感。
- /// - NavLink 相关成员均返回安全默认值(飞行单位不使用平台连接段)。
- /// - 目标到达后触发 事件(替代轮询 IsAtDestination)。
+ /// - 飞行单位直飞,无地形阻挡概念, 恒为 false。
///
///
/// 使用方式:挂载到飞行怪 Prefab 根节点,替代 EnemyNavAgent;
- /// 的 GetComponent<IPathAgent>() 自动发现此组件。
+ /// 的 GetComponent<IEnemyNavigator>() 自动发现此组件。
///
[RequireComponent(typeof(Rigidbody2D))]
- public sealed class FlyingDirectNavigator : MonoBehaviour, IPathAgent
+ public sealed class FlyingNavigator : MonoBehaviour, IEnemyNavigator
{
[Header("移动参数")]
[Tooltip("直飞速度(m/s)")]
@@ -27,7 +25,7 @@ namespace BaseGames.Enemies.Navigation
[Tooltip("到达目标的判定距离(m)")]
[SerializeField] private float _stoppingDist = 0.15f;
- [Header("游荡参数(WalkToRandom)")]
+ [Header("游荡参数(TryPickWanderPoint)")]
[Tooltip("随机游荡目标点距当前位置的最大半径(m)。")]
[Min(0.1f)]
[SerializeField] private float _randomWalkRadius = 3f;
@@ -42,33 +40,23 @@ namespace BaseGames.Enemies.Navigation
[Tooltip("横向方向翻转周期(s)")]
[SerializeField] private float _hoverFlipInterval = 1.5f;
- // ── IPathAgent 事件 ────────────────────────────────────────────
- public event Action OnLinkStarted { add { } remove { } }
- public event Action OnLinkCompleted { add { } remove { } }
- public event Action OnNavPathFailed { add { } remove { } }
- public event Action OnGoalReached;
-
// ── 状态 ───────────────────────────────────────────────────────
private Rigidbody2D _rb;
private EnemyMovement _movement;
- private Vector2? _destination;
- private bool _isMoving;
- private bool _goalFired;
+ private Vector2 _target;
+ private bool _hasTarget;
+ private bool _arrived;
private float _hoverTimer;
private float _hoverFlipTimer;
private float _hoverDir = 1f;
- // ── IPathAgent 属性 ────────────────────────────────────────────
- public bool IsMoving => _isMoving;
- public bool IsOnLink => false;
- public NavLinkType CurrentLinkType => NavLinkType.None;
- public Vector2 CurrentLinkStart => Vector2.zero;
- public Vector2 CurrentLinkEnd => Vector2.zero;
+ // ── IEnemyNavigator 属性 ────────────────────────────────────────
+ public bool IsMoving => _hasTarget && !_arrived;
+ public bool HasArrived => _arrived;
- // 飞行单位直飞、始终可达,无"受阻/最近可达点"概念。
- public bool LastMoveObstructed => false;
- public bool TryGetClosestReachable(out Vector2 worldPos) { worldPos = Vector2.zero; return false; }
+ // 飞行单位直飞,无地形阻挡概念。
+ public bool IsBlocked => false;
// ── Unity 生命周期 ─────────────────────────────────────────────
private void Awake()
@@ -81,56 +69,38 @@ namespace BaseGames.Enemies.Navigation
private void FixedUpdate()
{
- if (_destination.HasValue)
+ if (_hasTarget && !_arrived)
UpdateChase();
else
UpdateHover();
}
- // ── IPathAgent 方法 ────────────────────────────────────────────
- public void RequestMoveTo(Vector2 target)
+ // ── IEnemyNavigator 方法 ────────────────────────────────────────
+ public void MoveTowards(Vector2 target)
{
- _destination = target;
- _isMoving = true;
- _goalFired = false;
+ // 幂等:同目标重复调用不重置状态(避免每帧重发目标导致已到达状态被反复清空)。
+ if (_hasTarget && (target - _target).sqrMagnitude <= 1e-6f)
+ return;
+
+ _target = target;
+ _hasTarget = true;
+ _arrived = false;
}
- public void StopNavigation()
+ public void Stop()
{
- _destination = null;
- _isMoving = false;
+ _hasTarget = false;
+ _arrived = false;
_rb.velocity = Vector2.zero;
}
- public bool IsAtDestination()
- {
- if (!_destination.HasValue) return true;
- return ((Vector2)transform.position - _destination.Value).sqrMagnitude
- <= _stoppingDist * _stoppingDist;
- }
-
public void SetSpeed(float speed) => _moveSpeed = speed;
- public bool IsNearEdge() => false; // 飞行单位不检测平台边缘
-
- public bool CanReach(Vector2 target) => true; // 飞行单位直飞,始终可达
-
- public bool WalkToRandom()
+ public bool TryPickWanderPoint(out Vector2 point)
{
- // 在当前位置随机偏移一个 2D 方向(供 BD_WalkRandom 调用)
- Vector2 offset = UnityEngine.Random.insideUnitCircle.normalized * _randomWalkRadius;
- RequestMoveTo((Vector2)transform.position + offset);
- return true;
- }
-
- // 飞行单位无"导航段"概念,其 WalkToRandom 本就是当前位置的有界局部偏移,
- // 天然满足"就近游走"语义,直接复用。
- public bool WalkToRandomOnSegment() => WalkToRandom();
-
- // 飞行单位直飞、无地面/崖沿/身体宽度约束——任意目标本就"站得住",原样返回即可。
- public bool ResolveStandablePoint(Vector2 target, out Vector2 standable)
- {
- standable = target;
+ // 在当前位置随机偏移一个 2D 方向,供上层游荡状态调用;不主动发起移动。
+ Vector2 offset = Random.insideUnitCircle.normalized * _randomWalkRadius;
+ point = (Vector2)transform.position + offset;
return true;
}
@@ -138,19 +108,13 @@ namespace BaseGames.Enemies.Navigation
private void UpdateChase()
{
Vector2 myPos = _rb.position;
- Vector2 target = _destination.Value;
+ Vector2 target = _target;
float sqrDist = (target - myPos).sqrMagnitude;
if (sqrDist <= _stoppingDist * _stoppingDist)
{
_rb.velocity = Vector2.zero;
- _isMoving = false;
- _destination = null;
- if (!_goalFired)
- {
- _goalFired = true;
- OnGoalReached?.Invoke();
- }
+ _arrived = true;
return;
}
diff --git a/Assets/_Game/Scripts/Enemies/Navigation/FlyingDirectNavigator.cs.meta b/Assets/_Game/Scripts/Enemies/Navigation/FlyingNavigator.cs.meta
similarity index 100%
rename from Assets/_Game/Scripts/Enemies/Navigation/FlyingDirectNavigator.cs.meta
rename to Assets/_Game/Scripts/Enemies/Navigation/FlyingNavigator.cs.meta