@
test(ai): PerceptionStateMachine locomotion 意图回归测试(绿) 新增 PerceptionStateMachineTests:待机态声明 Idle locomotion 意图、进追逐区 转 Chase 并触发追击能力、Chase 态不再直接声明 locomotion 意图。测试程序集 补 BaseGames.Enemies 引用。断言经真实状态机 + 测试 fake 验证通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> @
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using BaseGames.AI;
|
||||||
|
using BaseGames.Enemies;
|
||||||
|
|
||||||
|
namespace BaseGames.Tests.EditMode.AI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 回归测试:PerceptionStateMachine 的待机/巡逻/警觉声明 locomotion 意图,
|
||||||
|
/// 追击走能力(不直接驱动 locomotion)。转换规则见 spec《敌人感知↔状态》。
|
||||||
|
/// </summary>
|
||||||
|
public class PerceptionStateMachineTests
|
||||||
|
{
|
||||||
|
static AiGraph Graph()
|
||||||
|
{
|
||||||
|
var b = new BrainBuilder();
|
||||||
|
PerceptionStateMachine.Add(b, new PerceptionStateMachine.Config
|
||||||
|
{
|
||||||
|
Idle = "Idle", Patrol = "Patrol", Alert = "Alert", Chase = "Chase",
|
||||||
|
Death = "Death", Entry = "Idle", Rest = "Patrol",
|
||||||
|
IdleMode = LocomotionMode.Idle,
|
||||||
|
PatrolMode = LocomotionMode.Patrol,
|
||||||
|
AlertMode = LocomotionMode.Face,
|
||||||
|
ChaseAbilityId = "chase",
|
||||||
|
});
|
||||||
|
return b.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void EntryIdleState_SetsIdleLocomotionMode()
|
||||||
|
{
|
||||||
|
var ctx = new FakeAiContext();
|
||||||
|
var rt = new AiRuntime(Graph(), ctx);
|
||||||
|
Assert.AreEqual("Idle", rt.CurrentStateName);
|
||||||
|
Assert.AreEqual(LocomotionMode.Idle, ctx.L.CurrentMode); // 进入待机即声明 Idle 意图
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void InChaseZone_TransitionsToChase_AndTriggersChaseAbility()
|
||||||
|
{
|
||||||
|
var ctx = new FakeAiContext();
|
||||||
|
var rt = new AiRuntime(Graph(), ctx);
|
||||||
|
ctx.S.Chase = true; // 进入追逐区
|
||||||
|
rt.Tick(0.1f);
|
||||||
|
Assert.AreEqual("Chase", rt.CurrentStateName);
|
||||||
|
CollectionAssert.Contains(ctx.C.Used, "chase"); // 追击由能力触发
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ChaseState_DoesNotDeclareLocomotionIntent()
|
||||||
|
{
|
||||||
|
// 追击移动归能力;AI 在 Chase 态不应再声明 SetMode/Approach/Face。
|
||||||
|
var ctx = new FakeAiContext();
|
||||||
|
var rt = new AiRuntime(Graph(), ctx);
|
||||||
|
ctx.S.Chase = true;
|
||||||
|
rt.Tick(0.1f); // Idle → Chase(退出 Idle 会调用一次 Stop)
|
||||||
|
int lastStop = ctx.L.Calls.FindLastIndex(s => s == "Stop");
|
||||||
|
var afterEnteringChase = ctx.L.Calls.GetRange(lastStop + 1, ctx.L.Calls.Count - lastStop - 1);
|
||||||
|
CollectionAssert.IsEmpty(afterEnteringChase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 11d9c7954aefbd84e93387db27268546
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
"BaseGames.Combat",
|
"BaseGames.Combat",
|
||||||
"BaseGames.Core",
|
"BaseGames.Core",
|
||||||
"BaseGames.AI",
|
"BaseGames.AI",
|
||||||
|
"BaseGames.Enemies",
|
||||||
"BaseGames.Core.Events",
|
"BaseGames.Core.Events",
|
||||||
"BaseGames.Core.Save",
|
"BaseGames.Core.Save",
|
||||||
"BaseGames.EventChain",
|
"BaseGames.EventChain",
|
||||||
|
|||||||
Reference in New Issue
Block a user