Files
zeling_v2/Assets/_Game/Scripts/Editor/AI/EnemyAiRecipeWizard.cs
T
joywayer ecdb0040cb feat(editor): 敌人 AI 配方脚手架向导;AssignModules 改名并失效缓存
- AiRecipeSO 新增 protected InvalidateGraph(),子类装配模块后调用以丢弃缓存图,
  避免改动要等到下次进 Play 才生效的静默陈旧图问题。
- PerceptionRecipeSO.SetModulesForTests 改名为 AssignModules(向导也要用它装配模块,
  旧名字具有误导性),并在装配后调用 InvalidateGraph。
- 新增 EnemyAiRecipeWizard:按 AssetFolderSpec 定名定路径创建感知型 AI 配方资产
  (Assets/_Game/Data/Enemies/{EnemyID}/ENM_{EnemyID}_Ai.asset),已存在则选中不覆盖。
- PerceptionRecipeSoTests 同步改名调用点,并新增测试钉住"装配后缓存必须失效"契约。
2026-07-29 15:28:25 +08:00

75 lines
2.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.IO;
using UnityEditor;
using UnityEngine;
using BaseGames.Enemies;
namespace BaseGames.Editor.AI
{
/// <summary>
/// 敌人 AI 配方脚手架。按 AssetFolderSpec 定名定路径:
/// Assets/_Game/Data/Enemies/{EnemyID}/ENM_{EnemyID}_Ai.asset
/// </summary>
public sealed class EnemyAiRecipeWizard : EditorWindow
{
const string DataRoot = "Assets/_Game/Data/Enemies";
string _enemyId = "E001";
[MenuItem("BaseGames/AI/Enemy AI Recipe Wizard")]
static void Open() => GetWindow<EnemyAiRecipeWizard>("敌人 AI 配方向导").minSize = new Vector2(420, 160);
void OnGUI()
{
EditorGUILayout.HelpBox(
"创建感知型 AI 配方资产。创建后在 Inspector 里选两层模块(未发现 / 交战)," +
"再把资产拖到敌人预制体的 EnemyAiBrain._recipe 上。",
MessageType.Info);
_enemyId = EditorGUILayout.TextField("敌人 ID(如 E001", _enemyId);
string path = TargetPath(_enemyId);
EditorGUILayout.LabelField("产出路径", path);
using (new EditorGUI.DisabledScope(string.IsNullOrWhiteSpace(_enemyId)))
{
if (GUILayout.Button("创建配方资产", GUILayout.Height(28)))
Create(_enemyId);
}
}
static string TargetPath(string enemyId) =>
$"{DataRoot}/{enemyId}/ENM_{enemyId}_Ai.asset";
/// <summary>建配方资产。已存在则选中返回,不覆盖用户已配好的内容。</summary>
public static PerceptionRecipeSO Create(string enemyId)
{
string dir = $"{DataRoot}/{enemyId}";
if (!AssetDatabase.IsValidFolder(dir))
{
Directory.CreateDirectory(dir);
AssetDatabase.Refresh();
}
string path = TargetPath(enemyId);
var existing = AssetDatabase.LoadAssetAtPath<PerceptionRecipeSO>(path);
if (existing != null)
{
Selection.activeObject = existing;
EditorGUIUtility.PingObject(existing);
Debug.Log($"配方已存在,已选中:{path}");
return existing;
}
var so = ScriptableObject.CreateInstance<PerceptionRecipeSO>();
AssetDatabase.CreateAsset(so, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Selection.activeObject = so;
EditorGUIUtility.PingObject(so);
Debug.Log($"✔ 已创建 AI 配方:{path}");
return so;
}
}
}