feat(enemy): 嘲风迁移到新轨——能力资产 + 对象树 + 开战触发
删 5 个空 BossSkillSO,用向导重建 6 个 EnemyAbilitySO(含入场演出)。 预制体经放置工具重新产出:EnemyAiBrain(_definitionId=ChaoFeng) + BossPhaseAbilityGate + 6 个能力组件,不再有 BossSkillExecutor。 TestRoomA 加开战触发区。三件自检 0 error,EditMode 260/260。 首次真正跑通两条脚手架,暴露并修掉三个它们的缺陷: 1. 放置工具漏挂 EnemyLocomotion(PlaceChaoFeng 及其余 7 个敌人放置入口)。 EnemyBase.Awake 找不到它即报错且 Locomotion 为 null, AiStateFragments.ApplyLocomotion 直接 NRE、AiRuntime 构造失败—— Boss 建不出决策层,完全不动。已在所有敌人放置入口补齐。 2. 向导把空中阶段的 wind_stone 建成 requiresGrounded=true(SO 默认值)。 Boss 浮空后 IsGrounded 恒 false,选招器把它滤掉,空中阶段站着不打。 能力定义表加 grounded 列,阶段 1 的招显式置 false。 3. BossPhaseAbilityGate.ApplyPhase 只在 EnterPhase 与 OnSpawn 调用, 直接摆场景里的 Boss 两条路径都不走,开局后续阶段的招仍在候选池里。 BossBase.Start 补一次初始阶段应用。 另:Phase1_Tornado_HitBox 确认零消费者(龙卷判定随弹体走), 从放置工具删除其创建与伤害源绑定; EnemyBrainContext.UseAbility 对解析不到的能力 id 改为 LogError, 不再静默返回 false(CLAUDE.md 第 6 条); 新增 PlaceBossFightTrigger 脚手架(此前无对应创建入口,属裸建)。 播放模式实测状态序列(TestRoomA,玩家走进触发区): Wait →(Engaged) Intro → Ground⇄GroundAttack →(hp<50%) PhaseTransition → Air⇄AirAttack,浮空生效,阶段门按阶段换池,全程 0 报错。 动画 Clip 未接入,PlayClipAbility 空 clip 立即完成,故只验证了状态流转, 判定时序待美术接入后再校。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -67,10 +67,26 @@ namespace BaseGames.Enemies
|
||||
public Vector2 LastKnown => _lastKnown;
|
||||
|
||||
// ---- ICombatant ----
|
||||
/// <summary>
|
||||
/// 执行指定 id 的能力。解析不到该 id 一律显式报错——
|
||||
/// 建图期 <c>AiStateFragments.Ability/AbilityOnce</c> 已挡掉空 id,
|
||||
/// 所以运行期解析不到只可能是漏挂能力组件或 SO 上的 abilityId 写错,没有合法情形。
|
||||
/// 静默返回 false 会让「能力态进入后什么都不做、IsAbilityRunning 恒假、
|
||||
/// 完成条件立刻成立」表现为"演出被跳过"却零报错(CLAUDE.md 第 6 条)。
|
||||
/// 用 LogError 而非抛异常:这是每帧路径,抛异常会打断整个 AiRuntime.Tick,
|
||||
/// 让一个漏配的敌人拖垮整场战斗。
|
||||
/// </summary>
|
||||
public bool UseAbility(string abilityId)
|
||||
{
|
||||
var a = _enemy.Abilities?.Get(abilityId);
|
||||
return a != null && a.Execute();
|
||||
if (a == null)
|
||||
{
|
||||
Debug.LogError($"[EnemyBrainContext] '{_enemy.name}' 的 AI 图请求能力 " +
|
||||
$"'{abilityId}',但该敌人身上没有这个能力组件。" +
|
||||
"请检查能力组件是否挂载、其 EnemyAbilitySO 的 abilityId 是否一致。", _enemy);
|
||||
return false;
|
||||
}
|
||||
return a.Execute();
|
||||
}
|
||||
public bool IsAbilityRunning(string abilityId = null)
|
||||
{
|
||||
|
||||
@@ -86,6 +86,16 @@ namespace BaseGames.Enemies
|
||||
if (_arenaAnchors == null) _arenaAnchors = GetComponentInChildren<BossArenaAnchors>(true);
|
||||
}
|
||||
|
||||
// 初始阶段的招池必须在第一次选招前就位。
|
||||
// ApplyPhase 此前只在 EnterPhase(阶段切换)与 OnSpawn(对象池复用)里调用,
|
||||
// 而直接摆在场景里的 Boss 两条路径都不走——开局时后续阶段的招式仍是 enabled,
|
||||
// 会混进阶段 0 的候选池。放在 Start:此时各能力组件的 Awake 均已执行完毕。
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
_phaseGate?.ApplyPhase(_currentPhase);
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
|
||||
Reference in New Issue
Block a user