- AiRecipeSO 新增 protected InvalidateGraph(),子类装配模块后调用以丢弃缓存图,
避免改动要等到下次进 Play 才生效的静默陈旧图问题。
- PerceptionRecipeSO.SetModulesForTests 改名为 AssignModules(向导也要用它装配模块,
旧名字具有误导性),并在装配后调用 InvalidateGraph。
- 新增 EnemyAiRecipeWizard:按 AssetFolderSpec 定名定路径创建感知型 AI 配方资产
(Assets/_Game/Data/Enemies/{EnemyID}/ENM_{EnemyID}_Ai.asset),已存在则选中不覆盖。
- PerceptionRecipeSoTests 同步改名调用点,并新增测试钉住"装配后缓存必须失效"契约。
46 lines
1.7 KiB
C#
46 lines
1.7 KiB
C#
using UnityEngine;
|
||
using BaseGames.Core.Events;
|
||
|
||
namespace BaseGames.AI
|
||
{
|
||
/// <summary>
|
||
/// AI 配方资产基类。子类以序列化字段描述一张图,Build 里组装。
|
||
/// 一个资产 = 一种敌人 AI;所有引用该资产的实例共享同一张 AiGraph(flyweight)。
|
||
/// </summary>
|
||
public abstract class AiRecipeSO : ScriptableObject, IAiDefinition
|
||
{
|
||
AiGraph _cached;
|
||
|
||
/// <summary>
|
||
/// 子类若要自己的 OnEnable,必须 override 本方法并调 base.OnEnable()——
|
||
/// 声明成 protected virtual 正是为此:若留作 private,子类另写一个 OnEnable 会
|
||
/// 静默遮蔽它(Unity 只调最派生的那个),缓存清理从此不再注册且无任何报错。
|
||
/// </summary>
|
||
protected virtual void OnEnable()
|
||
{
|
||
// 项目已关闭 Domain Reload:SO 的运行时态在多次 Play 会话间会残留,
|
||
// 改了配方再进 Play 仍用旧图。登记到统一的"进入 Play 前重置"通道。
|
||
PlayModeResetHook.Register(ClearCache);
|
||
}
|
||
|
||
void ClearCache() => _cached = null;
|
||
|
||
/// <summary>装配 / 修改模块后调用,丢弃已缓存的图。
|
||
/// 不调的话,改动要等到下次进入 Play 才生效——静默的陈旧图。</summary>
|
||
protected void InvalidateGraph() => _cached = null;
|
||
|
||
public AiGraph GetOrBuildGraph()
|
||
{
|
||
if (_cached == null)
|
||
{
|
||
var b = new BrainBuilder();
|
||
Build(b);
|
||
_cached = b.Build();
|
||
}
|
||
return _cached;
|
||
}
|
||
|
||
protected abstract void Build(BrainBuilder b);
|
||
}
|
||
}
|