diff --git a/Assets/_Game/Scripts/AI/AiRecipeSO.cs b/Assets/_Game/Scripts/AI/AiRecipeSO.cs new file mode 100644 index 00000000..935211f0 --- /dev/null +++ b/Assets/_Game/Scripts/AI/AiRecipeSO.cs @@ -0,0 +1,36 @@ +using UnityEngine; +using BaseGames.Core.Events; + +namespace BaseGames.AI +{ + /// + /// AI 配方资产基类。子类以序列化字段描述一张图,Build 里组装。 + /// 一个资产 = 一种敌人 AI;所有引用该资产的实例共享同一张 AiGraph(flyweight)。 + /// + public abstract class AiRecipeSO : ScriptableObject, IAiDefinition + { + AiGraph _cached; + + void OnEnable() + { + // 项目已关闭 Domain Reload:SO 的运行时态在多次 Play 会话间会残留, + // 改了配方再进 Play 仍用旧图。登记到统一的"进入 Play 前重置"通道。 + PlayModeResetHook.Register(ClearCache); + } + + void ClearCache() => _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); + } +} diff --git a/Assets/_Game/Scripts/AI/AiRecipeSO.cs.meta b/Assets/_Game/Scripts/AI/AiRecipeSO.cs.meta new file mode 100644 index 00000000..88bc0068 --- /dev/null +++ b/Assets/_Game/Scripts/AI/AiRecipeSO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b4ea7eede5a322448cfccec3eff2acf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Scripts/AI/AiScript.cs b/Assets/_Game/Scripts/AI/AiScript.cs index e5632de8..22fe173a 100644 --- a/Assets/_Game/Scripts/AI/AiScript.cs +++ b/Assets/_Game/Scripts/AI/AiScript.cs @@ -14,7 +14,7 @@ namespace BaseGames.AI /// 一种敌人 AI 的声明基类(唯一事实来源)。子类实现 Build 用 fluent 描述状态机。 /// 构建结果 AiGraph 每类型只建一次、实例共享(flyweight)。 /// - public abstract class AiScript + public abstract class AiScript : IAiDefinition { AiGraph _cached; diff --git a/Assets/_Game/Scripts/AI/BaseGames.AI.asmdef b/Assets/_Game/Scripts/AI/BaseGames.AI.asmdef index 2115deb7..30e9e706 100644 --- a/Assets/_Game/Scripts/AI/BaseGames.AI.asmdef +++ b/Assets/_Game/Scripts/AI/BaseGames.AI.asmdef @@ -2,7 +2,8 @@ "name": "BaseGames.AI", "rootNamespace": "BaseGames.AI", "references": [ - "BaseGames.Core" + "BaseGames.Core", + "BaseGames.Core.Events" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/_Game/Scripts/AI/IAiDefinition.cs b/Assets/_Game/Scripts/AI/IAiDefinition.cs new file mode 100644 index 00000000..53892a4d --- /dev/null +++ b/Assets/_Game/Scripts/AI/IAiDefinition.cs @@ -0,0 +1,12 @@ +namespace BaseGames.AI +{ + /// + /// 能产出共享 AiGraph 的东西。两个实现: + /// AiScript(定制路径,写 C# 类)与 AiRecipeSO(配方路径,建资产)。 + /// + public interface IAiDefinition + { + /// 惰性构建并缓存共享图(flyweight:每个定义只建一次)。 + AiGraph GetOrBuildGraph(); + } +} diff --git a/Assets/_Game/Scripts/AI/IAiDefinition.cs.meta b/Assets/_Game/Scripts/AI/IAiDefinition.cs.meta new file mode 100644 index 00000000..d680a12a --- /dev/null +++ b/Assets/_Game/Scripts/AI/IAiDefinition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdf86cde06fe7b8468b243b2bca11d22 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: