Files
zeling_v2/Assets/_Game/Scripts/Enemies/AIBrain/Ai/E001CaoZhiAi.cs
T
joywayerandClaude Opus 4.8 4ce798ea6e refactor(ai): E001 AI 重写为纯决策层,符合设计并委托能力模块
依据小怪设计文档重构 E001 状态机 Idle_Disguise→Skill_Start→Skill_Loop→Skill_End→Move_Patrol:
追击移动/接触伤害全部委托 e001_chase(ContactChaseAbility),AI 不再裸 MoveTo。
新增 ISensor.DetectsPlayer(视线OR近身,对齐设计)、IMover.UseChase/PatrolSpeed、
IEnemyActor.SetPhase(AI 声明阶段、EnemyBase 播动画)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 16:51:47 +08:00

56 lines
2.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BaseGames.AI;
namespace BaseGames.Enemies
{
/// <summary>
/// E001(草蛭)AI —— 纯决策层:只决定"进哪个状态 / 触发哪个能力 / 声明哪个阶段",
/// 追击移动与接触伤害由 e001_chase 能力(ContactChaseAbility)负责,AI 不自己实现。
/// 依据 Docs/Game/Design/小怪设计-程序开发文档-01.md 的 E001 状态机:
/// Idle_Disguise → Skill_Start → Skill_Loop → Skill_End → Move_Patrol,受击致死 → Death。
/// </summary>
[AiDefinition("E001")]
public sealed class E001CaoZhiAi : AiScript
{
// 阶段声明入口:AiPhase 属 Enemies 命名空间,经 IEnemyActor 暴露(EnemyBrainContext 实现)
static IEnemyActor Actor(IAiContext c) => (IEnemyActor)c;
protected override void Build(BrainBuilder b)
{
b.Entry("Idle_Disguise");
// 受到足够伤害 → 死亡(全局事件,最高优先)
b.Global().To("Death").OnEvent(AiSignal.Died);
// 伪装待机:静止蜷缩;感知玩家(视线 OR 近身触发圆) → 进入技能
b.State("Idle_Disguise")
.OnEnter(c => { c.Mover.Stop(); Actor(c).SetPhase(AiPhase.Idle); })
.To("Skill_Start").When(c => c.Sensor.DetectsPlayer(), "DetectsPlayer");
// 张口:触发一次性 e001_alert(占位/警觉停顿),播完转入追击
b.State("Skill_Start")
.OnEnter(c => { Actor(c).SetPhase(AiPhase.Alert); c.Combat.UseAbility("e001_alert"); })
.To("Skill_Loop").When(c => !c.Combat.IsAbilityRunning("e001_alert"), "alertDone");
// 快速追击:切追击速度 + 声明 Chase 阶段 + 触发 e001_chase 能力。
// 追击的 MoveTo / 接触伤害开关 / 丢失目标自结束,全部由能力负责,AI 只等它结束。
b.State("Skill_Loop")
.OnEnter(c => { c.Mover.UseChaseSpeed(); Actor(c).SetPhase(AiPhase.Chase); c.Combat.UseAbility("e001_chase"); })
.To("Skill_End").When(c => !c.Combat.IsAbilityRunning("e001_chase"), "chaseEnded");
// 收牙:短暂过渡后回巡逻(收牙动画待美术补 clip)
b.State("Skill_End")
.To("Move_Patrol").After(0.1f);
// 巡逻:低速爬行;感知玩家 → 再次进入技能
b.State("Move_Patrol")
.OnEnter(c => { c.Mover.UsePatrolSpeed(); Actor(c).SetPhase(AiPhase.Patrol); })
.Tick(c => c.Mover.WalkRandom())
.To("Skill_Start").When(c => c.Sensor.DetectsPlayer(), "DetectsPlayer");
// 死亡:停下(Death 动画走物理状态机 EnemyStateType.Dead
b.State("Death")
.OnEnter(c => c.Mover.Stop());
}
}
}