feat(ai): 新增 IBossControl facet——Boss 阶段状态经 IAiContext 供图读取

非 Boss 敌人访问 IAiContext.Boss 显式抛 InvalidOperationException,
不返回空对象掩盖小怪图误挂 Boss 边的错误。BossResource 补 IsFull 供图条件边判定。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-30 12:15:54 +08:00
co-authored by Claude Opus 5
parent 5839b423ae
commit 3665504a58
13 changed files with 176 additions and 4 deletions
@@ -51,10 +51,12 @@ namespace BaseGames.Tests.EditMode.AI
public FakeCombat C = new FakeCombat();
public FakeVitals V = new FakeVitals();
public Blackboard BB = new Blackboard();
public FakeBossControl B = new FakeBossControl();
public ISensor Sensor => S;
public IEnemyLocomotion Locomotion => L;
public ICombatant Combat => C;
public IActorVitals Vitals => V;
public Blackboard Blackboard => BB;
public IBossControl Boss => B;
}
}
@@ -0,0 +1,35 @@
using BaseGames.AI;
namespace BaseGames.Tests.EditMode.AI
{
public sealed class FakeBossControl : IBossControl
{
public int Phase;
public bool Transitioning;
public bool Full;
// 记录最近一次过渡请求,供断言"图确实发起了过渡"
public int LastTargetPhase = -1;
public float LastDuration = -1f;
public int BeginCallCount;
// 锚点:测试按下标直给坐标;距离由测试直接设定
public UnityEngine.Vector2[] Anchors = new UnityEngine.Vector2[0];
public float DistanceToAnchorValue;
public int CurrentPhase => Phase;
public bool IsPhaseTransitioning => Transitioning;
public bool ResourceFull => Full;
public void BeginPhaseTransition(int targetPhase, float invincibleDuration)
{
LastTargetPhase = targetPhase;
LastDuration = invincibleDuration;
BeginCallCount++;
Transitioning = true; // 由测试手工置回 false 模拟过渡结束
}
public UnityEngine.Vector2 AnchorAt(int index) => Anchors[index];
public float DistanceToAnchor(int index) => DistanceToAnchorValue;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dc93ec3a62b58c24da5b420bdeeed029
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: