@
feat(enemy): E001 追击改为冲刺+冷却(朝玩家方向冲,撞墙/边缘停,CD后再冲) 按新设计:进入追击→Skill_Start(张口)→起手后按玩家所在侧一次性确定方向→ 速度直冲(非 nav,接触伤害开)→撞墙/到平台边缘(WouldBlockAhead)或受阻即停→ Skill_End(收招)→进入冷却(ABL_E001_Chase.cooldown=1s)。一次冲刺=一次能力执行, AI 追击态在冷却结束时经 EnsureAbility 重触发下一次冲刺。 - ContactChaseAbility:无限跟随改为有限冲刺;方向 committed(会越过跳开的玩家, 可被躲);加窗口净位移卡死兜底——撞上未在检测层的碰撞体(玩家/边界墙)原地不动 时结束冲刺转收招+冷却,避免卡死。 - ABL_E001_Chase.cooldown 0→1(可在 SO 调)。 PlayMode 验证(净域重载后):Skill_Start→冲刺(实测冲 7 单位、伤害开)→受阻→ Skill_End→冷却→冷却结束重新起手冲刺,完整循环。速度直冲不依赖 nav,敌人实际 位移正常。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> @
This commit is contained in:
@@ -5,10 +5,11 @@ using UnityEngine;
|
||||
namespace BaseGames.Enemies.Abilities
|
||||
{
|
||||
/// <summary>
|
||||
/// 追击 + 体接触伤害能力:起手(Skill_Start 张口) → 循环追击(Skill_Loop 快速爬行 + 接触伤害)
|
||||
/// → 收招(Skill_End)。追击动画由本能力全权驱动(Approach 模式不驱动步态,避免抢动画)。
|
||||
/// 何时停止由 AI 决策层负责:AI 在"脱离感知"时中断本能力(ExternalRequest),本能力播 Skill_End 收招。
|
||||
/// 依据 Docs/Game/Design/小怪设计-程序开发文档-01.md(E001 状态机 Skill_Start/Loop/End)。
|
||||
/// 冲刺追击 + 体接触伤害能力:起手(Skill_Start 张口) → 朝玩家方向直冲(Skill_Loop 快速爬行 +
|
||||
/// 接触伤害),**直到撞墙/到平台边缘或玩家消失即停** → 收招(Skill_End)。一次冲刺为一次能力执行,
|
||||
/// 结束后进入冷却(EnemyAbilitySO.cooldown);AI 追击态在冷却结束时经 EnsureAbility 重触发下一次冲刺。
|
||||
/// 冲刺方向在起手后按玩家所在侧一次性确定(committed 冲锋,会越过跳开的玩家,可被躲)。
|
||||
/// 追击动画由本能力全权驱动(Approach 步态不抢动画)。
|
||||
/// </summary>
|
||||
public class ContactChaseAbility : EnemyAbilityBase
|
||||
{
|
||||
@@ -33,20 +34,38 @@ namespace BaseGames.Enemies.Abilities
|
||||
yield return EnemyAbilityWaits.Get(_startClip.Clip.length);
|
||||
}
|
||||
|
||||
// 循环追击:切追击速度、开接触伤害、朝玩家移动,播 Skill_Loop(Approach 模式不抢步态)。
|
||||
if (_enemy.Nav != null && _enemy.Stats != null)
|
||||
_enemy.Nav.SetSpeed(_enemy.Stats.RunSpeed);
|
||||
// 冲刺方向:起手后按玩家所在侧一次性确定(committed 冲锋)
|
||||
float dir = (_enemy.PlayerTransform != null &&
|
||||
_enemy.PlayerTransform.position.x < _enemy.transform.position.x) ? -1f : 1f;
|
||||
float speed = _enemy.Stats != null ? _enemy.Stats.RunSpeed : 0f;
|
||||
var mv = _enemy.Movement;
|
||||
|
||||
// 冲刺:朝该方向直冲、接触伤害开、播 Skill_Loop,直到撞墙/到边缘或玩家消失即停。
|
||||
if (_loopClip.Clip != null)
|
||||
_animancer.Play(_loopClip);
|
||||
if (_contactDamage != null)
|
||||
_contactDamage.enabled = true;
|
||||
|
||||
// 追击直到玩家消失或被 AI 中断(退出追击的决策归 AI)。小怪走 nav 寻路。
|
||||
_enemy.Locomotion?.Approach(_enemy.PlayerTransform);
|
||||
while (_enemy.PlayerTransform != null)
|
||||
float winX = _enemy.transform.position.x;
|
||||
float winT = 0f;
|
||||
while (_enemy.PlayerTransform != null && !(mv != null && mv.WouldBlockAhead(dir)))
|
||||
{
|
||||
_enemy.MoveInDirectionWithSpeed(dir, speed); // 速度直冲(非 nav),MoveWithSpeed 悬崖夹紧兜底
|
||||
yield return null;
|
||||
|
||||
// 玩家对象消失(正常收尾):收招 Skill_End。
|
||||
// 兜底:撞上未在检测层的碰撞体(玩家/边界墙)导致原地不动 → 结束本次冲刺(转收招+冷却)。
|
||||
// 用窗口净位移判定,避免"贴住微抖"每帧重置。
|
||||
winT += Time.deltaTime;
|
||||
if (winT >= 0.15f)
|
||||
{
|
||||
if (Mathf.Abs(_enemy.transform.position.x - winX) < 0.05f) break;
|
||||
winX = _enemy.transform.position.x;
|
||||
winT = 0f;
|
||||
}
|
||||
}
|
||||
_enemy.StopMovement();
|
||||
|
||||
// 收招 Skill_End;随后基类按 EnemyAbilitySO.cooldown 施加冷却。
|
||||
DisableContact();
|
||||
yield return PlaySkillEnd();
|
||||
Cleanup();
|
||||
|
||||
Reference in New Issue
Block a user