From 426fa3601d022fcebcc4dff9b2fea96df9a9b10d Mon Sep 17 00:00:00 2001 From: Joywayer Date: Wed, 29 Jul 2026 15:23:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(enemy):=20EnemyAiBrain=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=AE=88=E5=8D=AB=E4=B8=8D=E9=9A=8F=E9=87=8D=E6=96=B0=E5=90=AF?= =?UTF-8?q?=E7=94=A8=E8=92=B8=E5=8F=91=EF=BC=8C=E6=B3=A8=E5=86=8C=E8=A1=A8?= =?UTF-8?q?=E6=B6=88=E9=87=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/_Game/Scripts/AI/AiDefinitionRegistry.cs | 9 +-------- Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs | 10 +++++++++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Assets/_Game/Scripts/AI/AiDefinitionRegistry.cs b/Assets/_Game/Scripts/AI/AiDefinitionRegistry.cs index 5cada826..feb04305 100644 --- a/Assets/_Game/Scripts/AI/AiDefinitionRegistry.cs +++ b/Assets/_Game/Scripts/AI/AiDefinitionRegistry.cs @@ -48,14 +48,7 @@ namespace BaseGames.AI } /// 取 id 对应的共享 AiGraph;不存在则显式抛错(根因暴露,不做兜底)。 - public static AiGraph GetGraph(string id) - { - EnsureBuilt(); - if (!_byId.TryGetValue(id, out var script)) - throw new InvalidOperationException( - $"AiDefinitionRegistry: 未找到 AI 定义 id '{id}'。请确认存在 [AiDefinition(\"{id}\")] 的 AiScript 子类。"); - return script.GetOrBuildGraph(); - } + public static AiGraph GetGraph(string id) => GetDefinition(id).GetOrBuildGraph(); /// 取 id 对应的定义;不存在则显式抛错(根因暴露,不做兜底)。 public static IAiDefinition GetDefinition(string id) diff --git a/Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs b/Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs index da443b0d..d832b329 100644 --- a/Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs +++ b/Assets/_Game/Scripts/Enemies/AIBrain/EnemyAiBrain.cs @@ -20,7 +20,10 @@ namespace BaseGames.Enemies EnemyBase _enemy; EnemyBrainContext _context; AiRuntime _runtime; + bool _configValid; + /// 调试显示用。配方路径返回资产名、脚本路径返回定义 id——两者是不同的 + /// id 空间,**不要**拿它去 AiDefinitionRegistry 查表。 public string DefinitionId => _recipe != null ? _recipe.name : _definitionId; public string CurrentStateName => _runtime != null ? _runtime.CurrentStateName : "(none)"; public bool IsSuspended => _runtime != null && _runtime.IsSuspended; @@ -32,7 +35,8 @@ namespace BaseGames.Enemies bool hasRecipe = _recipe != null; bool hasId = !string.IsNullOrEmpty(_definitionId); - if (hasRecipe == hasId) // 都配了 或 都没配 + _configValid = hasRecipe != hasId; + if (!_configValid) { // 根因暴露:配置歧义 / 漏配直接报错,不静默兜底。 Debug.LogError( @@ -46,6 +50,10 @@ namespace BaseGames.Enemies // 再触发入口状态 OnEnter(其会声明 locomotion 意图)。所有 Awake 先于任一 Start 执行。 void Start() { + // 不依赖"禁用组件即跳过 Start"这一生命周期细节:组件若被事后重新启用, + // 配置仍然是错的,不能让它带着坏配置建图。 + if (!_configValid) return; + IAiDefinition definition = _recipe != null ? (IAiDefinition)_recipe : AiDefinitionRegistry.GetDefinition(_definitionId); // 不存在则抛异常