refactor(enemy): 清行为树债——StopBehaviorTree 改名,删 ConsumeParryEvent

StopBehaviorTree → NotifyDecisionStop(方法体早已只是发 Died 信号)。
EnemyDeathSequence 的 _stopBehaviorTree 字段同步改名,带 FormerlySerializedAs 保值。
ConsumeParryEvent 及其 TTL 状态删除:零调用者,且 ForceState(Stagger) +
IsControllable 让位门已是更优表达,不需要第二条受击通道。

顺带清掉这三个文件里残留的行为树插件措辞(BD_* / BD Task / 停行为树)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-30 16:23:47 +08:00
co-authored by Claude Opus 5
parent a44aafee3a
commit 822dc90c21
3 changed files with 26 additions and 47 deletions
+18 -40
View File
@@ -11,8 +11,8 @@ namespace BaseGames.Enemies
{
/// <summary>
/// 敌人基类(架构 07_EnemyModule §1)。
/// 实现 IDamageable,为 Behavior Designer 任务提供统一虚方法接口。
/// 包含:BD 接口、受击、死亡流程。
/// 实现 IDamageable,为 AI 决策层提供统一虚方法接口。
/// 包含:决策层接口、受击、死亡流程。
/// ⚠️ _nav 字段类型为 IEnemyNavigator(在 BaseGames.Enemies.Navigation 中实现具体类)。
/// 实现 IPoolable:配合 PooledObject 支持对象池复用,避免频繁 Destroy/Instantiate。
/// </summary>
@@ -49,7 +49,7 @@ namespace BaseGames.Enemies
[SerializeField] private Collider2D _bodyCollider;
[Header("区域(可选)")]
[Tooltip("地图固定巡逻/追击区域;配置后 BD_ChasePlayer 以区域边界替代 MaxChaseDistanceBD_ReturnToHome 归位至区域中心。留空则沿用出生点 + MaxChaseDistance 旧逻辑。")]
[Tooltip("地图固定巡逻/追击区域;配置后追击以区域边界替代 MaxChaseDistance,归位至区域中心。留空则沿用出生点 + MaxChaseDistance 旧逻辑。")]
[SerializeField] private EnemyPatrolZone _patrolZone;
[Header("事件频道")]
@@ -97,18 +97,18 @@ namespace BaseGames.Enemies
public EnemyStateType CurrentState => _currentState;
// ── 导航语义(归位 / 搜查)────────────────────────────────────────────
/// <summary>Awake/Start 时记录的初始世界坐标,供 BD_ReturnToHome 归位使用。</summary>
/// <summary>Awake/Start 时记录的初始世界坐标,供归位行为使用。</summary>
public Vector2 HomePosition { get; private set; }
/// <summary>
/// 玩家最后一次可见的世界坐标。
/// 由 BD_ChasePlayer 在持有视线时每帧更新;视线丢失后保留最后记录值供 BD_InvestigateLastKnown 使用。
/// 由追击行为在持有视线时每帧更新;视线丢失后保留最后记录值供「搜查最后已知位置」行为使用。
/// </summary>
public Vector2 LastKnownPlayerPosition { get; set; }
/// <summary>
/// 地图固定巡逻/追击区域(可选)。
/// 配置后 BD_ChasePlayer 以区域边界为追击上限;BD_ReturnToHome 归位至区域中心。
/// 配置后追击以区域边界为上限;归位至区域中心。
/// 未配置时退回旧逻辑(HomePosition + MaxChaseDistance)。
/// </summary>
public EnemyPatrolZone PatrolZone => _patrolZone;
@@ -222,7 +222,7 @@ namespace BaseGames.Enemies
public IEnemyLocomotion Locomotion => _locomotion ?? (_locomotion = GetComponentInChildren<IEnemyLocomotion>(true));
public EnemyMovement Movement => _movement;
public EnemyStats Stats => _stats;
/// <summary>敌人配置 SO,供 BD Task / 状态对象读取配置数据(如 knockUpDuration)。</summary>
/// <summary>敌人配置 SO,供 AI 决策层 / 状态对象读取配置数据(如 knockUpDuration)。</summary>
public EnemyStatsSO StatsSO => _statsSO;
public AnimancerComponent Animancer => _animancer;
public EnemyAnimationConfigSO AnimConfig => _animConfig;
@@ -234,9 +234,9 @@ namespace BaseGames.Enemies
private Abilities.EnemyAttackSelector _attackSelector;
/// <summary>身体碰撞体几何的唯一权威查询口。移动/导航/能力一律经此获取身体尺寸。</summary>
public IEnemyBody Body => _body ??= new EnemyBody(gameObject, _bodyCollider);
/// <summary>由 _onPlayerSpawned 事件缓存的玩家 Transform,供 BD 任务读取。</summary>
/// <summary>由 _onPlayerSpawned 事件缓存的玩家 Transform,供 AI 决策层读取。</summary>
public Transform PlayerTransform => _playerTransform;
/// <summary>感知 Hub;供 BD 任务及 QuotaManager 暂停/恢复感知使用。</summary>
/// <summary>感知 Hub;供 AI 决策层及 QuotaManager 暂停/恢复感知使用。</summary>
public Perception.IPerceptionSystem SensorHub => _sensorHub;
private Perception.IPerceptionSystem _sensorHub;
/// <summary>威胁评估器(可选):为原始 LOS 结果叠加反应延迟,使感知更自然。</summary>
@@ -253,7 +253,7 @@ namespace BaseGames.Enemies
public bool IsEngaged { get; private set; }
public void SetEngaged(bool engaged) => IsEngaged = engaged;
// ── BD 行为树接口(虚方法)────────────────────────────────────────
// ── AI 决策层接口(虚方法)──────────────────────────────────────
public virtual void MoveTo(Vector2 target)
=> _nav?.MoveTowards(target);
@@ -402,37 +402,16 @@ namespace BaseGames.Enemies
}
// ── 弹反(Parry)响应 ──────────────────────────────────────────────
private bool _wasParried;
private float _parryTimestamp;
// BD 树因阶段切换/死亡未能消费弹反事件时,超过此时长自动过期
private const float ParryEventTTL = 2f;
/// <summary>
/// 消费弹反事件标志(读取并清除)
/// BD_OnParried Conditional Task 在每次 Tick 时调用此方法
/// 若 BD 树因阶段切换或死亡未能及时消费,超过 TTL 后自动过期返回 false。
/// </summary>
public bool ConsumeParryEvent()
{
if (!_wasParried) return false;
if (Time.time - _parryTimestamp > ParryEventTTL)
{
_wasParried = false;
return false;
}
_wasParried = false;
return true;
}
/// <summary>
/// 被弹反时调用:强制进入 Stagger 状态并在 <paramref name="staggerDuration"/> 秒后恢复。
/// 由近战攻击碰到玩家弹反框时触发(例如 BossParryDetector 或通用 ParryDetector)。
/// 被弹反时调用:强制进入 Stagger 并在 staggerDuration 秒后恢复
/// Stagger 期间 IsControllable 为 falseAI 决策自动让位——不需要额外的 AI 信号
/// ⚠️ 目前**零调用者**:弹反管线(HurtBox → ParrySystem.ConsumeParry)拿不到攻击者引用,
/// 接线是一件独立任务(DamageInfo 加 attacker,或弹反成功时回调发起攻击的 HitBox)。
/// </summary>
public virtual void ReceiveParry(float staggerDuration = 0.5f)
{
if (!IsAlive) return;
_wasParried = true;
_parryTimestamp = Time.time;
ForceState(EnemyStateType.Stagger);
_abilities.InterruptAll(InterruptReason.Stagger);
ScheduleStateRecovery(EnemyStateType.Stagger, staggerDuration);
@@ -626,7 +605,7 @@ namespace BaseGames.Enemies
protected virtual void Start()
{
// 记录出生位置,供 BD_ReturnToHome 归位使用
// 记录出生位置,供归位行为使用
HomePosition = transform.position;
LastKnownPlayerPosition = transform.position;
@@ -659,11 +638,11 @@ namespace BaseGames.Enemies
protected virtual void OnDestroy() { }
/// <summary>
/// 通知决策层终止(死亡演出 / 出场演出期间调用,防止决策继续覆盖演出逻辑)。
/// 语义为"通知决策层终止",与 PerformDeath 的 Died 信号幂等(重复 Died 无害)。
/// 通知决策层终止(死亡演出 / 出场演出期间调用,防止决策继续覆盖演出逻辑)。
/// 与 PerformDeath 的 Died 信号幂等(重复 Died 无害)。
/// 供配置型行为组件(如 EnemyDeathSequence)调用,故为 public。
/// </summary>
public void StopBehaviorTree()
public void NotifyDecisionStop()
{
_brain?.Send(BaseGames.AI.AiSignal.Died);
}
@@ -752,7 +731,6 @@ namespace BaseGames.Enemies
// 重置对象池复用相关的运行时感知数据
// 注意:_playerTransform 不重置(场景中玩家仍存在),只重置追踪历史
LastKnownPlayerPosition = transform.position;
_wasParried = false;
_deathSequenceActive = false;
// 重置生命值