feat(enemy): 未发现层/交战层/死亡层三个模块契约

This commit is contained in:
2026-07-29 11:47:29 +08:00
parent 2643f58b08
commit 17e71dac39
6 changed files with 110 additions and 0 deletions
@@ -0,0 +1,16 @@
using BaseGames.AI;
namespace BaseGames.Enemies
{
/// <summary>
/// 死亡层:单态终结(演出交给物理状态机)/ 单段死亡能力 / 两段演出(可带生成物)。
/// 骨架只挂一条 Global → EntryState 的 Died 事件边,链条内容全归本模块。
/// </summary>
public interface IDeathModule
{
void Build(BrainBuilder b);
/// <summary>骨架全局死亡边指向的态。</summary>
string EntryState { get; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ca95968c577c65244bfb6c5a9a908ef4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,31 @@
using System;
using BaseGames.AI;
namespace BaseGames.Enemies
{
/// <summary>
/// 交战层:发现玩家之后怎么打。骨架只认这四件事——从哪个态进、什么条件进、
/// 边标签是什么、内部怎么打。新增一种打法 = 新增一个实现,骨架与其他模块不受影响。
///
/// CanEngage 归本模块所有是关键:像"冲锋冷却门"这种只对某一种打法有意义的条件,
/// 若留在骨架上就会变成骨架的开关字段,并与其他开关互相耦合。
///
/// 实现注意:模块会经 [SerializeReference] 反序列化,构造函数不保证被调用。
/// 不要在构造函数里预计算缓存或做参数校验——缓存用惰性属性,校验放 Build()。
/// </summary>
public interface IEngagementModule
{
/// <summary>声明交战态与脱战边。</summary>
/// <param name="rest">脱战后回到的未发现态,由骨架传入。</param>
void Build(BrainBuilder b, string rest);
/// <summary>骨架从未发现态 / 警觉态连过来的目标。</summary>
string EntryState { get; }
/// <summary>进入交战的条件。惰性构建并缓存。</summary>
Func<IAiContext, bool> CanEngage { get; }
/// <summary>CanEngage 的可读标签(trace / 图导出用)。</summary>
string EngageLabel { get; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0941f7f7a28a5374fbfd2971bde2ef54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,30 @@
using System.Collections.Generic;
using BaseGames.AI;
namespace BaseGames.Enemies
{
/// <summary>
/// 未发现层:玩家尚未被发现时的行为形状(单一站桩 / 单向降级 / 定时交替 …)。
///
/// 刻意拆成两阶段:AiRuntime 按声明顺序评估条件边,若本模块的内部边(如巡逻计时)
/// 早于骨架的升级边声明,玩家进入追逐区那一帧若恰好计时到点,敌人会切去另一个待机态
/// 而不是扑上来。骨架的调用顺序固定为 Declare → 挂升级边 → Link。
/// </summary>
public interface IUnawareModule
{
/// <summary>只声明状态与行为回调,不挂任何转换。</summary>
void Declare(BrainBuilder b);
/// <summary>挂内部转换(如站立 ⇄ 巡逻的计时边)。没有内部边的模块留空实现。</summary>
void Link(BrainBuilder b);
/// <summary>图入口(出生态)。</summary>
string Entry { get; }
/// <summary>脱战 / 警觉丢失后回到的态。必须属于 States。</summary>
string Rest { get; }
/// <summary>需要挂升级边的所有未发现态。</summary>
IReadOnlyList<string> States { get; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bad88c851589dbe4fa0efbb66331e399
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: