From 499436092784f5783eb0ac3c7aa8232167b7ea1a Mon Sep 17 00:00:00 2001 From: Joywayer Date: Fri, 3 Jul 2026 15:00:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(ai):=20EnemyAiBrain=20=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E2=80=94=E2=80=94=E6=89=BF=E8=BD=BD=20AiRuntime=E3=80=81?= =?UTF-8?q?=E9=80=90=E5=B8=A7=E6=8E=A8=E8=BF=9B=E3=80=81=E6=B1=A0=E5=A4=8D?= =?UTF-8?q?=E7=94=A8=E9=87=8D=E7=BD=AE=E3=80=81=E4=BF=A1=E5=8F=B7=E5=85=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Scripts/Enemies/AIBrain/EnemyAiBrain.cs | 59 +++++++++++++++++++ .../Enemies/AIBrain/EnemyAiBrain.cs.meta | 11 ++++ 2 files changed, 70 insertions(+) create mode 100644 Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs create mode 100644 Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs.meta diff --git a/Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs b/Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs new file mode 100644 index 00000000..c92c460a --- /dev/null +++ b/Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs @@ -0,0 +1,59 @@ +using UnityEngine; +using BaseGames.AI; + +namespace BaseGames.Enemies +{ + /// + /// 把 BrainGraph 决策层挂到敌人上:按 id 取共享 AiGraph、构造 AiRuntime、逐帧推进。 + /// 取代旧的行为树组件。 + /// + [DisallowMultipleComponent] + [RequireComponent(typeof(EnemyBase))] + public sealed class EnemyAiBrain : MonoBehaviour + { + [Tooltip("对应 [AiDefinition(id)] 的敌人 AI 定义 id,例如 E001")] + [SerializeField] string _definitionId; + + EnemyBase _enemy; + EnemyBrainContext _context; + AiRuntime _runtime; + + public string DefinitionId => _definitionId; + public string CurrentStateName => _runtime != null ? _runtime.CurrentStateName : "(none)"; + public bool IsSuspended => _runtime != null && _runtime.IsSuspended; + public AiRuntime Runtime => _runtime; + + void Awake() + { + _enemy = GetComponent(); + if (string.IsNullOrEmpty(_definitionId)) + { + // 根因暴露:漏配 id 直接报错,不静默兜底。 + Debug.LogError($"EnemyAiBrain 未配置 _definitionId:{name}", this); + enabled = false; + return; + } + var graph = AiDefinitionRegistry.GetGraph(_definitionId); // 不存在则抛异常 + _context = new EnemyBrainContext(_enemy); + _runtime = new AiRuntime(graph, _context); + } + + void Update() + { + if (_runtime == null) return; + float dt = Time.deltaTime; + _context.Refresh(dt); + _runtime.Tick(dt); + } + + /// 对象池复用时由 EnemyBase.OnSpawn 调用:回到 Entry、清临时态。 + public void ResetBrain() + { + _context?.ResetScratch(); + _runtime?.Reset(); + } + + /// 信号入口,供 EnemyBase 转发死亡等事件到决策层。 + public void Send(AiSignal signal) => _runtime?.Send(signal); + } +} diff --git a/Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs.meta b/Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs.meta new file mode 100644 index 00000000..0ca70084 --- /dev/null +++ b/Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d92d657c6bbdfe246a7333e04f79f8f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: