From 49627d357dd8a1e8440b03b97048168456c18414 Mon Sep 17 00:00:00 2001 From: Joywayer Date: Tue, 28 Jul 2026 11:17:34 +0800 Subject: [PATCH] =?UTF-8?q?refactor(enemy):=20FlyingDirectNavigator=20?= =?UTF-8?q?=E6=94=B9=E5=90=8D=20FlyingNavigator=20=E5=B9=B6=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=88=B0=20IEnemyNavigator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...gDirectNavigator.cs => FlyingNavigator.cs} | 102 ++++++------------ ...igator.cs.meta => FlyingNavigator.cs.meta} | 0 2 files changed, 33 insertions(+), 69 deletions(-) rename Assets/_Game/Scripts/Enemies/Navigation/{FlyingDirectNavigator.cs => FlyingNavigator.cs} (53%) rename Assets/_Game/Scripts/Enemies/Navigation/{FlyingDirectNavigator.cs.meta => FlyingNavigator.cs.meta} (100%) 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