From 82ce9ff09a2d9a598783ae79d565687b6b9425f1 Mon Sep 17 00:00:00 2001 From: Joywayer Date: Wed, 20 May 2026 11:52:17 +0800 Subject: [PATCH] refactor(editor): reorganize Editor directory and unify menu hierarchy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit File directory changes (mirror Scripts/ module structure): - AbilityTypeDrawer.cs → Equipment/ - CharacterWizardWindow.cs → Character/ - FormEditorWindow.cs → Player/ - GMToolWindow.cs → Tools/ - SOManagerWindow.cs → Tools/ - Map/MapRoomDataEditor.cs → World/Map/ - Navigation/ (root) → Enemies/Navigation/ - Achievements/ → Progression/ Menu hierarchy changes (BaseGames/ top-level): - Data/: +Character Wizard (from Tools/), +Boss Skill Sequence (from Tools/) - Addressables/: +Addressable Batch Tool, +Asset Reference Graph, +Validate Address Keys (from Tools/Verification/) - Scene/Setup/: +Boot Flow Wizard, +Scaffold *, +Auto-Open Persistent (from Tools/) - Scene/: +Camera Area Setup (from Camera/), +Bake All NavSurfaces (from Tools/) - Events/: +Event Bus Monitor, +Event Chain Viewer, +Create/Reimport Event Channels (from Tools/) - Tools/Validation/: +Validate All SOs, +Apply/Validate Script Order (from Tools/ flat) - Tools/Maintenance/: +Missing Scripts/*, +Physics2D Layer Matrix/* (from Tools/ flat) Result: BaseGames/Tools/ reduced from 16 flat items to 4 items + 2 submenus Docs: update AssetFolderSpec §12 editor tool table with new menu paths Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../AddressReferenceGraphWindow.cs | 2 +- .../Addressables/AddressableBatchTool.cs | 4 +- .../AddressableRuleSyncWindow.cs.meta | 11 +++ .../Addressables/AddressableRules.cs.meta | 11 +++ .../Editor/Camera/RoomCameraSetupTool.cs | 2 +- .../{Achievements.meta => Character.meta} | 2 +- .../{ => Character}/CharacterWizardWindow.cs | 2 +- .../CharacterWizardWindow.cs.meta | 0 .../Editor/Enemies/BossSkillSequenceWindow.cs | 2 +- .../Editor/{ => Enemies}/Navigation.meta | 2 +- .../Navigation/NavSurfaceBakeShortcut.cs | 4 +- .../Navigation/NavSurfaceBakeShortcut.cs.meta | 0 .../{ => Equipment}/AbilityTypeDrawer.cs | 0 .../{ => Equipment}/AbilityTypeDrawer.cs.meta | 0 .../EventChain/EventChainEditorWindow.cs | 2 +- .../Editor/Events/CreateEventChannelAssets.cs | 4 +- .../Editor/Events/EventBusMonitorWindow.cs | 2 +- Assets/_Game/Scripts/Editor/Player.meta | 8 ++ .../Editor/{ => Player}/FormEditorWindow.cs | 0 .../{ => Player}/FormEditorWindow.cs.meta | 0 Assets/_Game/Scripts/Editor/Progression.meta | 8 ++ .../AchievementSOEditor.cs | 0 .../AchievementSOEditor.cs.meta | 0 .../Editor/Scene/BootFlowSetupWizard.cs | 2 +- .../Editor/Scene/PersistentSceneAutoLoader.cs | 4 +- .../Editor/Scene/SceneScaffoldTools.cs | 6 +- .../Editor/{ => Tools}/GMToolWindow.cs | 0 .../Editor/{ => Tools}/GMToolWindow.cs.meta | 0 .../Editor/Tools/MissingScriptCleaner.cs | 8 +- .../Editor/Tools/Physics2DLayerReport.cs | 4 +- .../Editor/{ => Tools}/SOManagerWindow.cs | 0 .../{ => Tools}/SOManagerWindow.cs.meta | 0 .../Editor/Tools/SOValidationRunner.cs | 2 +- .../Editor/Tools/ScriptExecutionOrderTools.cs | 4 +- .../_Game/Scripts/Editor/{ => World}/Map.meta | 2 +- .../{ => World}/Map/MapRoomDataEditor.cs | 0 .../{ => World}/Map/MapRoomDataEditor.cs.meta | 0 Docs/Standards/AssetFolderSpec.md | 78 +++++++++++-------- 38 files changed, 115 insertions(+), 61 deletions(-) create mode 100644 Assets/_Game/Scripts/Editor/Addressables/AddressableRuleSyncWindow.cs.meta create mode 100644 Assets/_Game/Scripts/Editor/Addressables/AddressableRules.cs.meta rename Assets/_Game/Scripts/Editor/{Achievements.meta => Character.meta} (77%) rename Assets/_Game/Scripts/Editor/{ => Character}/CharacterWizardWindow.cs (99%) rename Assets/_Game/Scripts/Editor/{ => Character}/CharacterWizardWindow.cs.meta (100%) rename Assets/_Game/Scripts/Editor/{ => Enemies}/Navigation.meta (77%) rename Assets/_Game/Scripts/Editor/{ => Enemies}/Navigation/NavSurfaceBakeShortcut.cs (96%) rename Assets/_Game/Scripts/Editor/{ => Enemies}/Navigation/NavSurfaceBakeShortcut.cs.meta (100%) rename Assets/_Game/Scripts/Editor/{ => Equipment}/AbilityTypeDrawer.cs (100%) rename Assets/_Game/Scripts/Editor/{ => Equipment}/AbilityTypeDrawer.cs.meta (100%) create mode 100644 Assets/_Game/Scripts/Editor/Player.meta rename Assets/_Game/Scripts/Editor/{ => Player}/FormEditorWindow.cs (100%) rename Assets/_Game/Scripts/Editor/{ => Player}/FormEditorWindow.cs.meta (100%) create mode 100644 Assets/_Game/Scripts/Editor/Progression.meta rename Assets/_Game/Scripts/Editor/{Achievements => Progression}/AchievementSOEditor.cs (100%) rename Assets/_Game/Scripts/Editor/{Achievements => Progression}/AchievementSOEditor.cs.meta (100%) rename Assets/_Game/Scripts/Editor/{ => Tools}/GMToolWindow.cs (100%) rename Assets/_Game/Scripts/Editor/{ => Tools}/GMToolWindow.cs.meta (100%) rename Assets/_Game/Scripts/Editor/{ => Tools}/SOManagerWindow.cs (100%) rename Assets/_Game/Scripts/Editor/{ => Tools}/SOManagerWindow.cs.meta (100%) rename Assets/_Game/Scripts/Editor/{ => World}/Map.meta (77%) rename Assets/_Game/Scripts/Editor/{ => World}/Map/MapRoomDataEditor.cs (100%) rename Assets/_Game/Scripts/Editor/{ => World}/Map/MapRoomDataEditor.cs.meta (100%) diff --git a/Assets/_Game/Scripts/Editor/Addressables/AddressReferenceGraphWindow.cs b/Assets/_Game/Scripts/Editor/Addressables/AddressReferenceGraphWindow.cs index 216a61c..5763206 100644 --- a/Assets/_Game/Scripts/Editor/Addressables/AddressReferenceGraphWindow.cs +++ b/Assets/_Game/Scripts/Editor/Addressables/AddressReferenceGraphWindow.cs @@ -34,7 +34,7 @@ namespace BaseGames.Editor private static readonly Color ColMissing = new Color(0.95f, 0.55f, 0.10f, 0.80f); // 无效 Key(不在 Addressables) private static readonly Color ColOk = new Color(0.20f, 0.75f, 0.30f, 0.80f); // 正常 - [MenuItem("BaseGames/Tools/Asset Reference Graph")] + [MenuItem("BaseGames/Addressables/Asset Reference Graph")] public static void OpenWindow() { var win = GetWindow("Asset Reference Graph"); diff --git a/Assets/_Game/Scripts/Editor/Addressables/AddressableBatchTool.cs b/Assets/_Game/Scripts/Editor/Addressables/AddressableBatchTool.cs index 4cc3244..3cad8b2 100644 --- a/Assets/_Game/Scripts/Editor/Addressables/AddressableBatchTool.cs +++ b/Assets/_Game/Scripts/Editor/Addressables/AddressableBatchTool.cs @@ -25,7 +25,7 @@ namespace BaseGames.Editor { // ── 常量 ───────────────────────────────────────────────────────────── private const string Title = "Addressable 批量工具"; - private const string MenuPath = "BaseGames/Tools/Addressable Batch Tool"; + private const string MenuPath = "BaseGames/Addressables/Addressable Batch Tool"; private const string PrefsKey = "AddressableBatch."; // ── 状态 ───────────────────────────────────────────────────────────── @@ -77,7 +77,7 @@ namespace BaseGames.Editor // ───────────────────────────────────────────────────────────────────── [MenuItem(MenuPath, priority = 200)] - [MenuItem("BaseGames/Verification/Open Addressable Batch Tool", priority = 250)] + [MenuItem("BaseGames/Addressables/Open Addressable Batch Tool", priority = 250)] public static void OpenWindow() { var win = GetWindow(Title); diff --git a/Assets/_Game/Scripts/Editor/Addressables/AddressableRuleSyncWindow.cs.meta b/Assets/_Game/Scripts/Editor/Addressables/AddressableRuleSyncWindow.cs.meta new file mode 100644 index 0000000..5ef3561 --- /dev/null +++ b/Assets/_Game/Scripts/Editor/Addressables/AddressableRuleSyncWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0547dd5099c322248a3a2652f4b01cc9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Scripts/Editor/Addressables/AddressableRules.cs.meta b/Assets/_Game/Scripts/Editor/Addressables/AddressableRules.cs.meta new file mode 100644 index 0000000..cd8409c --- /dev/null +++ b/Assets/_Game/Scripts/Editor/Addressables/AddressableRules.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 195ffa39c13090d4e94d81ab10b6c721 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Scripts/Editor/Camera/RoomCameraSetupTool.cs b/Assets/_Game/Scripts/Editor/Camera/RoomCameraSetupTool.cs index 98117be..4da4d2d 100644 --- a/Assets/_Game/Scripts/Editor/Camera/RoomCameraSetupTool.cs +++ b/Assets/_Game/Scripts/Editor/Camera/RoomCameraSetupTool.cs @@ -42,7 +42,7 @@ namespace BaseGames.Editor private readonly Dictionary _soCache = new Dictionary(); // ══ 菜单入口 ══════════════════════════════════════════════════════════ - [MenuItem("BaseGames/Camera/Camera Area Setup", priority = 100)] + [MenuItem("BaseGames/Scene/Camera Area Setup", priority = 100)] public static void ShowWindow() { var win = GetWindow("Camera Area Setup"); diff --git a/Assets/_Game/Scripts/Editor/Achievements.meta b/Assets/_Game/Scripts/Editor/Character.meta similarity index 77% rename from Assets/_Game/Scripts/Editor/Achievements.meta rename to Assets/_Game/Scripts/Editor/Character.meta index 7f96797..98f2c10 100644 --- a/Assets/_Game/Scripts/Editor/Achievements.meta +++ b/Assets/_Game/Scripts/Editor/Character.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 07ed02361aa3739468cbd36457aecda6 +guid: c58b8b4e1f9da6a42ac3d362d4bf4014 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/_Game/Scripts/Editor/CharacterWizardWindow.cs b/Assets/_Game/Scripts/Editor/Character/CharacterWizardWindow.cs similarity index 99% rename from Assets/_Game/Scripts/Editor/CharacterWizardWindow.cs rename to Assets/_Game/Scripts/Editor/Character/CharacterWizardWindow.cs index 0ef62ac..6f3f63b 100644 --- a/Assets/_Game/Scripts/Editor/CharacterWizardWindow.cs +++ b/Assets/_Game/Scripts/Editor/Character/CharacterWizardWindow.cs @@ -38,7 +38,7 @@ namespace BaseGames.Editor private static StyleSheet Uss => _uss != null ? _uss : (_uss = AssetDatabase.LoadAssetAtPath(UssPath)); - [MenuItem("BaseGames/Tools/Character Wizard", priority = 1)] + [MenuItem("BaseGames/Data/Character Wizard", priority = 1)] public static void Open() { var wnd = GetWindow(); diff --git a/Assets/_Game/Scripts/Editor/CharacterWizardWindow.cs.meta b/Assets/_Game/Scripts/Editor/Character/CharacterWizardWindow.cs.meta similarity index 100% rename from Assets/_Game/Scripts/Editor/CharacterWizardWindow.cs.meta rename to Assets/_Game/Scripts/Editor/Character/CharacterWizardWindow.cs.meta diff --git a/Assets/_Game/Scripts/Editor/Enemies/BossSkillSequenceWindow.cs b/Assets/_Game/Scripts/Editor/Enemies/BossSkillSequenceWindow.cs index e2970c6..70b5fe7 100644 --- a/Assets/_Game/Scripts/Editor/Enemies/BossSkillSequenceWindow.cs +++ b/Assets/_Game/Scripts/Editor/Enemies/BossSkillSequenceWindow.cs @@ -39,7 +39,7 @@ namespace BaseGames.Editor private static readonly Color ColDelay = new Color(0.25f, 0.25f, 0.30f, 0.50f); private static readonly Color ColWarn = new Color(0.95f, 0.10f, 0.10f, 0.85f); - [MenuItem("BaseGames/Tools/Boss Skill Sequence Viewer")] + [MenuItem("BaseGames/Data/Boss Skill Sequence", priority = 110)] public static void OpenWindow() { var win = GetWindow("Boss Skill Sequence"); diff --git a/Assets/_Game/Scripts/Editor/Navigation.meta b/Assets/_Game/Scripts/Editor/Enemies/Navigation.meta similarity index 77% rename from Assets/_Game/Scripts/Editor/Navigation.meta rename to Assets/_Game/Scripts/Editor/Enemies/Navigation.meta index d73f3cc..6d7ca00 100644 --- a/Assets/_Game/Scripts/Editor/Navigation.meta +++ b/Assets/_Game/Scripts/Editor/Enemies/Navigation.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 763f62796f2f4ed43a21dfe3befb70a1 +guid: f8e429c47dfa7fe4da6d9687c02398ea folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/_Game/Scripts/Editor/Navigation/NavSurfaceBakeShortcut.cs b/Assets/_Game/Scripts/Editor/Enemies/Navigation/NavSurfaceBakeShortcut.cs similarity index 96% rename from Assets/_Game/Scripts/Editor/Navigation/NavSurfaceBakeShortcut.cs rename to Assets/_Game/Scripts/Editor/Enemies/Navigation/NavSurfaceBakeShortcut.cs index cf330d1..ab0305a 100644 --- a/Assets/_Game/Scripts/Editor/Navigation/NavSurfaceBakeShortcut.cs +++ b/Assets/_Game/Scripts/Editor/Enemies/Navigation/NavSurfaceBakeShortcut.cs @@ -18,7 +18,7 @@ namespace BaseGames.Editor private static readonly PropertyInfo s_bakeJobProp = typeof(NavSurface).GetProperty("BakeJob", BindingFlags.NonPublic | BindingFlags.Instance); - [MenuItem("BaseGames/Tools/Bake All NavSurfaces %#b", priority = 100)] + [MenuItem("BaseGames/Scene/Bake All NavSurfaces %#b", priority = 100)] public static void BakeAll() { var surfaces = Object.FindObjectsByType(FindObjectsSortMode.None); @@ -42,7 +42,7 @@ namespace BaseGames.Editor Debug.Log($"[NavSurfaceBake] 开始烘焙 {count} 个 NavSurface……"); } - [MenuItem("BaseGames/Tools/Bake All NavSurfaces %#b", validate = true)] + [MenuItem("BaseGames/Scene/Bake All NavSurfaces %#b", validate = true)] private static bool BakeAllValidate() { // 仅在非 Play Mode 时可用(NavSurface.Bake 仅支持编辑器模式) diff --git a/Assets/_Game/Scripts/Editor/Navigation/NavSurfaceBakeShortcut.cs.meta b/Assets/_Game/Scripts/Editor/Enemies/Navigation/NavSurfaceBakeShortcut.cs.meta similarity index 100% rename from Assets/_Game/Scripts/Editor/Navigation/NavSurfaceBakeShortcut.cs.meta rename to Assets/_Game/Scripts/Editor/Enemies/Navigation/NavSurfaceBakeShortcut.cs.meta diff --git a/Assets/_Game/Scripts/Editor/AbilityTypeDrawer.cs b/Assets/_Game/Scripts/Editor/Equipment/AbilityTypeDrawer.cs similarity index 100% rename from Assets/_Game/Scripts/Editor/AbilityTypeDrawer.cs rename to Assets/_Game/Scripts/Editor/Equipment/AbilityTypeDrawer.cs diff --git a/Assets/_Game/Scripts/Editor/AbilityTypeDrawer.cs.meta b/Assets/_Game/Scripts/Editor/Equipment/AbilityTypeDrawer.cs.meta similarity index 100% rename from Assets/_Game/Scripts/Editor/AbilityTypeDrawer.cs.meta rename to Assets/_Game/Scripts/Editor/Equipment/AbilityTypeDrawer.cs.meta diff --git a/Assets/_Game/Scripts/Editor/EventChain/EventChainEditorWindow.cs b/Assets/_Game/Scripts/Editor/EventChain/EventChainEditorWindow.cs index 5d9c4c0..68e30b3 100644 --- a/Assets/_Game/Scripts/Editor/EventChain/EventChainEditorWindow.cs +++ b/Assets/_Game/Scripts/Editor/EventChain/EventChainEditorWindow.cs @@ -35,7 +35,7 @@ namespace BaseGames.Editor private static readonly Color ColActive = new Color(0.95f, 0.60f, 0.10f, 0.80f); private static readonly Color ColPending = new Color(0.70f, 0.70f, 0.75f, 0.80f); - [MenuItem("BaseGames/Tools/Event Chain Viewer")] + [MenuItem("BaseGames/Events/Event Chain Viewer")] public static void OpenWindow() { var win = GetWindow("Event Chain Viewer"); diff --git a/Assets/_Game/Scripts/Editor/Events/CreateEventChannelAssets.cs b/Assets/_Game/Scripts/Editor/Events/CreateEventChannelAssets.cs index 1987510..91d7751 100644 --- a/Assets/_Game/Scripts/Editor/Events/CreateEventChannelAssets.cs +++ b/Assets/_Game/Scripts/Editor/Events/CreateEventChannelAssets.cs @@ -18,7 +18,7 @@ namespace BaseGames.Editor { private const string RootPath = "Assets/_Game/Data/Events"; - [MenuItem("BaseGames/Tools/Create Event Channel Assets")] + [MenuItem("BaseGames/Events/Create Event Channels")] public static void CreateAll() { // ── Core 原始类型频道 ────────────────────────────────────────────── @@ -115,7 +115,7 @@ namespace BaseGames.Editor Debug.Log("[CreateEventChannelAssets] 所有事件频道资产生成完毕。"); } - [MenuItem("BaseGames/Tools/Reimport Event Channel Assets")] + [MenuItem("BaseGames/Events/Reimport Event Channels")] public static void ReimportAllEventAssets() { if (!AssetDatabase.IsValidFolder(RootPath)) diff --git a/Assets/_Game/Scripts/Editor/Events/EventBusMonitorWindow.cs b/Assets/_Game/Scripts/Editor/Events/EventBusMonitorWindow.cs index dbbcad6..1f5c001 100644 --- a/Assets/_Game/Scripts/Editor/Events/EventBusMonitorWindow.cs +++ b/Assets/_Game/Scripts/Editor/Events/EventBusMonitorWindow.cs @@ -13,7 +13,7 @@ namespace BaseGames.Editor private bool _autoScroll = true; private Vector2 _scroll; - [MenuItem("BaseGames/Tools/Event Bus Monitor %#e")] + [MenuItem("BaseGames/Events/Event Bus Monitor %#e")] public static void OpenWindow() { EventBusMonitorWindow window = GetWindow("Event Bus Monitor"); diff --git a/Assets/_Game/Scripts/Editor/Player.meta b/Assets/_Game/Scripts/Editor/Player.meta new file mode 100644 index 0000000..bfc9705 --- /dev/null +++ b/Assets/_Game/Scripts/Editor/Player.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 89f2177f5a1c33044a6c38a2633f0ade +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Scripts/Editor/FormEditorWindow.cs b/Assets/_Game/Scripts/Editor/Player/FormEditorWindow.cs similarity index 100% rename from Assets/_Game/Scripts/Editor/FormEditorWindow.cs rename to Assets/_Game/Scripts/Editor/Player/FormEditorWindow.cs diff --git a/Assets/_Game/Scripts/Editor/FormEditorWindow.cs.meta b/Assets/_Game/Scripts/Editor/Player/FormEditorWindow.cs.meta similarity index 100% rename from Assets/_Game/Scripts/Editor/FormEditorWindow.cs.meta rename to Assets/_Game/Scripts/Editor/Player/FormEditorWindow.cs.meta diff --git a/Assets/_Game/Scripts/Editor/Progression.meta b/Assets/_Game/Scripts/Editor/Progression.meta new file mode 100644 index 0000000..c0da093 --- /dev/null +++ b/Assets/_Game/Scripts/Editor/Progression.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 172d69bd8cc35c34197a1974bd9cc9c3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Scripts/Editor/Achievements/AchievementSOEditor.cs b/Assets/_Game/Scripts/Editor/Progression/AchievementSOEditor.cs similarity index 100% rename from Assets/_Game/Scripts/Editor/Achievements/AchievementSOEditor.cs rename to Assets/_Game/Scripts/Editor/Progression/AchievementSOEditor.cs diff --git a/Assets/_Game/Scripts/Editor/Achievements/AchievementSOEditor.cs.meta b/Assets/_Game/Scripts/Editor/Progression/AchievementSOEditor.cs.meta similarity index 100% rename from Assets/_Game/Scripts/Editor/Achievements/AchievementSOEditor.cs.meta rename to Assets/_Game/Scripts/Editor/Progression/AchievementSOEditor.cs.meta diff --git a/Assets/_Game/Scripts/Editor/Scene/BootFlowSetupWizard.cs b/Assets/_Game/Scripts/Editor/Scene/BootFlowSetupWizard.cs index b12ffd6..f8a4e13 100644 --- a/Assets/_Game/Scripts/Editor/Scene/BootFlowSetupWizard.cs +++ b/Assets/_Game/Scripts/Editor/Scene/BootFlowSetupWizard.cs @@ -51,7 +51,7 @@ namespace BaseGames.Editor // ── 菜单入口 ────────────────────────────────────────────────────────── - [MenuItem("BaseGames/Tools/Boot Flow Wizard", priority = 10)] + [MenuItem("BaseGames/Scene/Setup/Boot Flow Wizard", priority = 10)] public static void Open() { var wnd = GetWindow(); diff --git a/Assets/_Game/Scripts/Editor/Scene/PersistentSceneAutoLoader.cs b/Assets/_Game/Scripts/Editor/Scene/PersistentSceneAutoLoader.cs index 9ed708c..205d26b 100644 --- a/Assets/_Game/Scripts/Editor/Scene/PersistentSceneAutoLoader.cs +++ b/Assets/_Game/Scripts/Editor/Scene/PersistentSceneAutoLoader.cs @@ -15,13 +15,13 @@ namespace BaseGames.Editor /// 运行时(Play Mode / 发行版 Build)的保证由 GameBootstrap(Runtime 程序集)负责, /// 本脚本与 Play Mode 状态无关,不监听 playModeStateChanged。 /// - /// 菜单:BaseGames/Tools/Edit Mode: Auto-Open Persistent Scene + /// 菜单:BaseGames/Scene/Setup/Auto-Open Persistent Scene /// [InitializeOnLoad] public static class PersistentSceneAutoLoader { // ── 常量 ───────────────────────────────────────────────────────────── - private const string MenuPath = "BaseGames/Tools/Edit Mode: Auto-Open Persistent Scene"; + private const string MenuPath = "BaseGames/Scene/Setup/Auto-Open Persistent Scene"; private const string PrefKey = "BaseGames_EditAutoOpen_Persistent"; private const string PersistentSceneName = "Scene_Persistent"; diff --git a/Assets/_Game/Scripts/Editor/Scene/SceneScaffoldTools.cs b/Assets/_Game/Scripts/Editor/Scene/SceneScaffoldTools.cs index d916217..93bf1ce 100644 --- a/Assets/_Game/Scripts/Editor/Scene/SceneScaffoldTools.cs +++ b/Assets/_Game/Scripts/Editor/Scene/SceneScaffoldTools.cs @@ -26,7 +26,7 @@ namespace BaseGames.Editor public static class SceneScaffoldTools { - [MenuItem("BaseGames/Tools/Scaffold Persistent Scene")] + [MenuItem("BaseGames/Scene/Setup/Scaffold Persistent Scene")] public static void ScaffoldPersistentScene() { var report = new List(); @@ -235,7 +235,7 @@ namespace BaseGames.Editor /// [MainMenu] → [Canvas_MainMenu] → 主按钮组 / SaveSlotPanel / SettingsPanel / CreditsPanel /// 自动绑定所有已存在的相关事件频道 SO 资产。 /// - [MenuItem("BaseGames/Tools/Scaffold Main Menu Scene", priority = 202)] + [MenuItem("BaseGames/Scene/Setup/Scaffold Main Menu Scene", priority = 202)] public static void ScaffoldMainMenuScene() { var report = new List(); @@ -305,7 +305,7 @@ namespace BaseGames.Editor /// [RoomRoot] → [Camera] / [SpawnPoints] / [Environment] / [Transitions] /// 可配合 SceneObjectPlacerTool 在层级内快速追加更多对象。 /// - [MenuItem("BaseGames/Tools/Scaffold Game Room", priority = 201)] + [MenuItem("BaseGames/Scene/Setup/Scaffold Game Room", priority = 201)] public static void ScaffoldGameRoom() { var report = new List(); diff --git a/Assets/_Game/Scripts/Editor/GMToolWindow.cs b/Assets/_Game/Scripts/Editor/Tools/GMToolWindow.cs similarity index 100% rename from Assets/_Game/Scripts/Editor/GMToolWindow.cs rename to Assets/_Game/Scripts/Editor/Tools/GMToolWindow.cs diff --git a/Assets/_Game/Scripts/Editor/GMToolWindow.cs.meta b/Assets/_Game/Scripts/Editor/Tools/GMToolWindow.cs.meta similarity index 100% rename from Assets/_Game/Scripts/Editor/GMToolWindow.cs.meta rename to Assets/_Game/Scripts/Editor/Tools/GMToolWindow.cs.meta diff --git a/Assets/_Game/Scripts/Editor/Tools/MissingScriptCleaner.cs b/Assets/_Game/Scripts/Editor/Tools/MissingScriptCleaner.cs index 72733b9..d360998 100644 --- a/Assets/_Game/Scripts/Editor/Tools/MissingScriptCleaner.cs +++ b/Assets/_Game/Scripts/Editor/Tools/MissingScriptCleaner.cs @@ -15,7 +15,7 @@ namespace BaseGames.Editor // 场景 // ────────────────────────────────────────────── - [MenuItem("BaseGames/Tools/Missing Scripts/Clear In Scene")] + [MenuItem("BaseGames/Tools/Maintenance/Missing Scripts/Clear In Scene")] public static void ClearMissingScriptsInScene() { int totalRemoved = 0; @@ -39,7 +39,7 @@ namespace BaseGames.Editor Debug.Log($"[MissingScriptCleaner] 场景完成。共移除 {totalRemoved} 个丢失脚本,影响 {affected.Count} 个 GameObject。"); } - [MenuItem("BaseGames/Tools/Missing Scripts/Find In Scene")] + [MenuItem("BaseGames/Tools/Maintenance/Missing Scripts/Find In Scene")] public static void FindMissingScriptsInScene() { int totalFound = 0; @@ -67,7 +67,7 @@ namespace BaseGames.Editor // Prefab 资产 // ────────────────────────────────────────────── - [MenuItem("BaseGames/Tools/Missing Scripts/Clear In All Prefabs")] + [MenuItem("BaseGames/Tools/Maintenance/Missing Scripts/Clear In All Prefabs")] public static void ClearMissingScriptsInPrefabs() { int totalRemoved = 0; @@ -107,7 +107,7 @@ namespace BaseGames.Editor Debug.Log($"[MissingScriptCleaner] Prefab 完成。共移除 {totalRemoved} 个丢失脚本,影响 {affectedPrefabs} 个 Prefab。"); } - [MenuItem("BaseGames/Tools/Missing Scripts/Find In All Prefabs")] + [MenuItem("BaseGames/Tools/Maintenance/Missing Scripts/Find In All Prefabs")] public static void FindMissingScriptsInPrefabs() { int totalFound = 0; diff --git a/Assets/_Game/Scripts/Editor/Tools/Physics2DLayerReport.cs b/Assets/_Game/Scripts/Editor/Tools/Physics2DLayerReport.cs index cd9c7cd..5f35e52 100644 --- a/Assets/_Game/Scripts/Editor/Tools/Physics2DLayerReport.cs +++ b/Assets/_Game/Scripts/Editor/Tools/Physics2DLayerReport.cs @@ -54,14 +54,14 @@ namespace BaseGames.Editor }; // ───────────────────────────────────────────────────────────────────── - [MenuItem("BaseGames/Tools/Physics2D Layer Matrix/Check", priority = 210)] + [MenuItem("BaseGames/Tools/Maintenance/Physics2D Layer Matrix/Check", priority = 210)] public static void CheckAndPrintReport() { var results = Check(); PrintToConsole(results); } - [MenuItem("BaseGames/Tools/Physics2D Layer Matrix/Auto Fix", priority = 211)] + [MenuItem("BaseGames/Tools/Maintenance/Physics2D Layer Matrix/Auto Fix", priority = 211)] public static void FixAndReport() { var results = Check(); diff --git a/Assets/_Game/Scripts/Editor/SOManagerWindow.cs b/Assets/_Game/Scripts/Editor/Tools/SOManagerWindow.cs similarity index 100% rename from Assets/_Game/Scripts/Editor/SOManagerWindow.cs rename to Assets/_Game/Scripts/Editor/Tools/SOManagerWindow.cs diff --git a/Assets/_Game/Scripts/Editor/SOManagerWindow.cs.meta b/Assets/_Game/Scripts/Editor/Tools/SOManagerWindow.cs.meta similarity index 100% rename from Assets/_Game/Scripts/Editor/SOManagerWindow.cs.meta rename to Assets/_Game/Scripts/Editor/Tools/SOManagerWindow.cs.meta diff --git a/Assets/_Game/Scripts/Editor/Tools/SOValidationRunner.cs b/Assets/_Game/Scripts/Editor/Tools/SOValidationRunner.cs index faf6dc4..b9a0480 100644 --- a/Assets/_Game/Scripts/Editor/Tools/SOValidationRunner.cs +++ b/Assets/_Game/Scripts/Editor/Tools/SOValidationRunner.cs @@ -31,7 +31,7 @@ namespace BaseGames.Editor + string.Join("\n", errors)); } - [MenuItem("BaseGames/Tools/Validate All ScriptableObjects")] + [MenuItem("BaseGames/Tools/Validation/Validate All ScriptableObjects")] public static void ValidateMenu() { var (errors, warnings) = RunAll(); diff --git a/Assets/_Game/Scripts/Editor/Tools/ScriptExecutionOrderTools.cs b/Assets/_Game/Scripts/Editor/Tools/ScriptExecutionOrderTools.cs index fdef5d5..7a44cf3 100644 --- a/Assets/_Game/Scripts/Editor/Tools/ScriptExecutionOrderTools.cs +++ b/Assets/_Game/Scripts/Editor/Tools/ScriptExecutionOrderTools.cs @@ -32,7 +32,7 @@ namespace BaseGames.Editor new OrderRule("PlayerController", -100), }; - [MenuItem("BaseGames/Tools/Apply Script Execution Order Preset")] + [MenuItem("BaseGames/Tools/Validation/Apply Script Execution Order Preset")] public static void ApplyPreset() { int updated = 0; @@ -69,7 +69,7 @@ namespace BaseGames.Editor Debug.Log($"[ScriptExecutionOrderTools] 执行顺序预设应用完成。更新数量: {updated}。"); } - [MenuItem("BaseGames/Tools/Validate Script Execution Order Preset")] + [MenuItem("BaseGames/Tools/Validation/Validate Script Execution Order Preset")] public static void ValidatePreset() { var mismatches = new List(); diff --git a/Assets/_Game/Scripts/Editor/Map.meta b/Assets/_Game/Scripts/Editor/World/Map.meta similarity index 77% rename from Assets/_Game/Scripts/Editor/Map.meta rename to Assets/_Game/Scripts/Editor/World/Map.meta index e66df0b..ef63621 100644 --- a/Assets/_Game/Scripts/Editor/Map.meta +++ b/Assets/_Game/Scripts/Editor/World/Map.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 08a52815a08c8c3428ccb6a530171ddd +guid: a1f0dd89654be0841be1adfcea426a67 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/_Game/Scripts/Editor/Map/MapRoomDataEditor.cs b/Assets/_Game/Scripts/Editor/World/Map/MapRoomDataEditor.cs similarity index 100% rename from Assets/_Game/Scripts/Editor/Map/MapRoomDataEditor.cs rename to Assets/_Game/Scripts/Editor/World/Map/MapRoomDataEditor.cs diff --git a/Assets/_Game/Scripts/Editor/Map/MapRoomDataEditor.cs.meta b/Assets/_Game/Scripts/Editor/World/Map/MapRoomDataEditor.cs.meta similarity index 100% rename from Assets/_Game/Scripts/Editor/Map/MapRoomDataEditor.cs.meta rename to Assets/_Game/Scripts/Editor/World/Map/MapRoomDataEditor.cs.meta diff --git a/Docs/Standards/AssetFolderSpec.md b/Docs/Standards/AssetFolderSpec.md index 318efec..bc7fb8a 100644 --- a/Docs/Standards/AssetFolderSpec.md +++ b/Docs/Standards/AssetFolderSpec.md @@ -652,11 +652,11 @@ var (prefab, _) = await AssetLoader.LoadAsync(AddressKeys.PrefabPlay 4. 在 Animations/ 下创建动画片段(.anim)和 Animator Controller 5. 在 Materials/ 下创建材质(引用 _Game/Shaders/ 中的角色 Shader,关联主纹理和 Emission 贴图) 6. 在 Atlases/ 下创建 Atlas_Enemy_{ID}.spriteatlas,包含该敌人所有 Sprite -7. 在 Enemy Data Manager(菜单 BaseGames → Data → Enemy Data Manager)创建 ENM_{ID}_Stats.asset +7. 在 Enemy Data Manager(菜单 BaseGames/Data/Enemy Data Manager)创建 ENM_{ID}_Stats.asset 8. 在 _Game/Prefabs/Enemies/{EnemyID}/ 下创建 ENM_{Name}.prefab 9. 在 AddressKeys.cs 中添加 PrefabEnemy{Name} 常量 -10. 使用 Rule Sync(菜单 BaseGames → Addressables → Rule Sync)Scan → Fix All,自动分组并打 Enemy 标签 -11. 运行 AddressKeyValidator(菜单 BaseGames → Verification → Validate Address Keys)验证 +10. 使用 Rule Sync(菜单 BaseGames/Addressables/Rule Sync)Scan → Fix All,自动分组并打 Enemy 标签 +11. 运行 AddressKeyValidator(菜单 BaseGames/Addressables/Validate Address Keys)验证 ``` ### 10.2 新增武器(Weapon) @@ -665,10 +665,10 @@ var (prefab, _) = await AssetLoader.LoadAsync(AddressKeys.PrefabPlay ``` 1. 在 _Game/Art/Characters/Player/{FormID}/Sprites/ 下放置武器帧动画 Sprite Sheet,配置 Import Settings -2. 在 Weapon Editor(菜单 BaseGames → Data → Weapon Editor)左栏 [New] 创建 WPN_{Name}_Data.asset +2. 在 Weapon Editor(菜单 BaseGames/Data/Weapon Editor)左栏 [New] 创建 WPN_{Name}_Data.asset - 路径:_Game/Data/Combat/Weapons/WPN_{Name}_Data.asset - 命名:WPN_{Name}(示例:WPN_SkyBlade、WPN_EarthClaw) -3. 使用 Weapon HitBox Wizard(菜单 BaseGames → Create → Weapon HitBox Prefab)生成 +3. 使用 Weapon HitBox Wizard(菜单 BaseGames/Create/Weapon HitBox Prefab)生成 _Game/Prefabs/Weapons/WPN_{Name}_HitBox.prefab(自动创建 4 方向 Ground/Up/Down/Air) 4. 在 _Game/Prefabs/Player/ 下创建或更新武器顶级 Prefab WPN_{Name}.prefab 5. 在 AddressKeys.cs 中添加 PrefabWeapon{Name} 常量 @@ -682,10 +682,10 @@ var (prefab, _) = await AssetLoader.LoadAsync(AddressKeys.PrefabPlay ``` 1. 在 _Game/Art/Characters/Player/{FormID}/Animations/ 下创建技能动画片段(.anim) -2. 在 Skill Editor(菜单 BaseGames → Data → Skill Editor)左栏 [New] 创建 SKL_{SkillID}_Data.asset +2. 在 Skill Editor(菜单 BaseGames/Data/Skill Editor)左栏 [New] 创建 SKL_{SkillID}_Data.asset - 路径:_Game/Data/Player/Skills/SKL_{SkillID}_Data.asset - 命名:SKL_{SkillID}(示例:SKL_DashSlash、SKL_SpiritWave) -3. 使用 Skill HitBox Wizard(菜单 BaseGames → Create → Skill HitBox Prefab)生成 +3. 使用 Skill HitBox Wizard(菜单 BaseGames/Create/Skill HitBox Prefab)生成 _Game/Prefabs/Skills/SKL_{SkillID}_HitBox.prefab(支持多段伤害配置) 4. 在 AddressKeys.cs 中添加对应常量(如需独立 Addressable 加载) 5. 运行 AddressKeyValidator 验证(如已注册 Addressable) @@ -709,11 +709,11 @@ var (prefab, _) = await AssetLoader.LoadAsync(AddressKeys.PrefabPlay > **推荐工具**:`BaseGames → Tools → Character Wizard`(`CharacterWizardWindow`)统一入口——创建 FormSO、绑定武器引用、跳转到 Form Editor;`BaseGames → Data → Form Editor`(`FormEditorWindow`)进行三魂列阵可视化编辑。 ``` -1. 在 Character Wizard(菜单 BaseGames → Tools → Character Wizard)切换到 Player 标签 +1. 在 Character Wizard(菜单 BaseGames/Data/Character Wizard)切换到 Player 标签 - 填写 FormID,点击 [Create Form Assets],自动在正确路径创建 FormSO 和相关 SO 2. 在 _Game/Art/Characters/Player/{FormID}/ 下创建 Sprites/ Animations/ Materials/ Atlases/ 目录 3. 导入 Sprite Sheet,配置 Import Settings(PPU=32, Filter=Point, Multiple) -4. 在 Form Editor(菜单 BaseGames → Data → Form Editor)三栏网格中选择形态格位,绑定武器和技能列表 +4. 在 Form Editor(菜单 BaseGames/Data/Form Editor)三栏网格中选择形态格位,绑定武器和技能列表 5. 在 _Game/Prefabs/Player/ 下创建 PLY_{FormID}.prefab 6. 在 AddressKeys.cs 中添加 PrefabPlayer{FormID} 常量(如为独立 Addressable) 7. 使用 Rule Sync 自动分组(Player 组)并打 Preload 标签 @@ -783,40 +783,56 @@ var (prefab, _) = await AssetLoader.LoadAsync(AddressKeys.PrefabPlay | 工具名称 | 菜单路径 | 负责资产类型 | 说明 | |---------|---------|------------|------| -| **Character Wizard** | `BaseGames → Tools → Character Wizard` | 角色 SO(玩家形态 / Minion / Boss 通用入口) | 统一入口,自动在正确路径创建所有配套 SO,内含快捷跳转按钮 | -| **Form Editor** | `BaseGames → Data → Form Editor` | 玩家三魂形态(FormSO) | 三栏可视化网格,自动绑定武器/技能引用,支持 TianHun / DiHun / MingHun | -| **Enemy Data Manager** | `BaseGames → Data → Enemy Data Manager` | 敌人配置 SO(`ENM_*_Stats.asset`)+ 掉落表 | 双面板列表编辑,左栏搜索 + [New],右栏 Stats/Loot 标签 | -| **Weapon Editor** | `BaseGames → Data → Weapon Editor` | 武器配置 SO(`WPN_*_Data.asset`) | 双面板列表,右栏全属性 + HitBox Prefab 验证 + 快捷操作 | -| **Weapon HitBox Wizard** | `BaseGames → Create → Weapon HitBox Prefab` | 武器 HitBox Prefab(4 方向 Ground/Up/Down/Air) | 自动生成 `WPN_{ID}_HitBox.prefab`,支持各方向碰撞体形状配置 | -| **Skill Editor** | `BaseGames → Data → Skill Editor` | 技能配置 SO(`SKL_*_Data.asset`) | 按 SkillEffectType 分组筛选,右栏含 HitBox 验证 + 资源费预览 | -| **Skill HitBox Wizard** | `BaseGames → Create → Skill HitBox Prefab` | 技能 HitBox Prefab(多段伤害支持) | 自动生成 `SKL_{ID}_HitBox.prefab`,可配置 1–4 段 hitBoxCount | -| **Boss Skill Sequence** | `BaseGames → Tools → Boss Skill Sequence Viewer` | Boss 技能阶段(BossSkillSO / SkillSequenceSO) | Gantt 时间轴可视化,Windup / Active / Recovery 三段颜色标记 | +| **Character Wizard** | `BaseGames/Data/Character Wizard` | 角色 SO(玩家形态 / Minion / Boss 通用入口) | 统一入口,自动在正确路径创建所有配套 SO,内含快捷跳转按钮 | +| **Form Editor** | `BaseGames/Data/Form Editor` | 玩家三魂形态(FormSO) | 三栏可视化网格,自动绑定武器/技能引用,支持 TianHun / DiHun / MingHun | +| **Enemy Data Manager** | `BaseGames/Data/Enemy Data Manager` | 敌人配置 SO(`ENM_*_Stats.asset`)+ 掉落表 | 双面板列表编辑,左栏搜索 + [New],右栏 Stats/Loot 标签 | +| **Boss Skill Sequence** | `BaseGames/Data/Boss Skill Sequence` | Boss 技能阶段(BossSkillSO / SkillSequenceSO) | Gantt 时间轴可视化,Windup / Active / Recovery 三段颜色标记 | +| **Skill Editor** | `BaseGames/Data/Skill Editor` | 技能配置 SO(`SKL_*_Data.asset`) | 按 SkillEffectType 分组筛选,右栏含 HitBox 验证 + 资源费预览 | +| **Weapon Editor** | `BaseGames/Data/Weapon Editor` | 武器配置 SO(`WPN_*_Data.asset`) | 双面板列表,右栏全属性 + HitBox Prefab 验证 + 快捷操作 | +| **Weapon HitBox Wizard** | `BaseGames/Create/Weapon HitBox Prefab` | 武器 HitBox Prefab(4 方向 Ground/Up/Down/Air) | 自动生成 `WPN_{ID}_HitBox.prefab`,支持各方向碰撞体形状配置 | +| **Skill HitBox Wizard** | `BaseGames/Create/Skill HitBox Prefab` | 技能 HitBox Prefab(多段伤害支持) | 自动生成 `SKL_{ID}_HitBox.prefab`,可配置 1–4 段 hitBoxCount | ### 12.2 场景搭建工具 | 工具名称 | 菜单路径 | 说明 | |---------|---------|------| -| **Boot Flow Wizard** | `BaseGames → Tools → Boot Flow Wizard` | 4 步启动流程一键配置(事件频道 → Persistent 场景 → MainMenu → 验证) | -| **Scene Scaffold** | `BaseGames → Tools → Scaffold Persistent Scene` | 一键创建 Persistent 场景的 Services/Input/Camera/UI 层次结构 | -| **Scene Object Placer** | `BaseGames → Scene → Place → {类型}` | 场景中快速放置角色/陷阱/检查点/摄像机等,自动绑定组件和事件频道 | -| **Persistent Auto-Loader** | `BaseGames → Tools → Edit Mode: Auto-Open Persistent Scene` | 编辑模式下打开任意场景时自动附加 Persistent(仅编辑模式) | +| **Boot Flow Wizard** | `BaseGames/Scene/Setup/Boot Flow Wizard` | 4 步启动流程一键配置(事件频道 → Persistent 场景 → MainMenu → 验证) | +| **Scaffold Persistent Scene** | `BaseGames/Scene/Setup/Scaffold Persistent Scene` | 一键创建 Persistent 场景的 Services/Input/Camera/UI 层次结构 | +| **Scaffold Main Menu Scene** | `BaseGames/Scene/Setup/Scaffold Main Menu Scene` | 一键创建 MainMenu 场景基础层次结构 | +| **Scaffold Game Room** | `BaseGames/Scene/Setup/Scaffold Game Room` | 一键创建关卡房间场景基础层次结构 | +| **Persistent Auto-Loader** | `BaseGames/Scene/Setup/Auto-Open Persistent Scene` | 编辑模式下打开任意场景时自动附加 Persistent(Toggle,仅编辑模式) | +| **Scene Object Placer** | `BaseGames/Scene/Place/{类型}` | 场景中快速放置角色/陷阱/检查点/摄像机等,自动绑定组件和事件频道 | +| **Camera Area Setup** | `BaseGames/Scene/Camera Area Setup` | 在当前场景中快速创建并配置摄像机区域 | +| **Bake All NavSurfaces** | `BaseGames/Scene/Bake All NavSurfaces` (Ctrl+Shift+B) | 一键烘焙场景中所有 NavSurface,仅编辑模式可用 | ### 12.3 Addressables 管理工具 | 工具名称 | 菜单路径 | 说明 | |---------|---------|------| -| **Rule Sync** | `BaseGames → Addressables → Rule Sync` | 批量扫描/修复分组和标签(基于 `AddressableRules.cs` 规则,支持导出 CSV) | -| **Addressable Batch Tool** | `BaseGames → Tools → Addressable Batch Tool` | 三标签操作:① 同步 AddressKeys → ② 文件夹批量注册 → ③ Selection 注册 | -| **Validate Address Keys** | `BaseGames → Verification → Validate Address Keys` | 验证 `AddressKeys.cs` 所有常量在 Addressables 中均已注册,构建前自动触发 | +| **Rule Sync** | `BaseGames/Addressables/Rule Sync` | 批量扫描/修复分组和标签(基于 `AddressableRules.cs` 规则,支持导出 CSV) | +| **Addressable Batch Tool** | `BaseGames/Addressables/Addressable Batch Tool` (Alt+Shift+A) | 三标签操作:① 同步 AddressKeys → ② 文件夹批量注册 → ③ Selection 注册 | +| **Asset Reference Graph** | `BaseGames/Addressables/Asset Reference Graph` | 可视化 Addressable 地址间的引用依赖关系 | +| **Validate Address Keys** | `BaseGames/Addressables/Validate Address Keys` | 验证 `AddressKeys.cs` 所有常量在 Addressables 中均已注册,构建前自动触发 | -### 12.4 数据/调试工具 +### 12.4 事件系统工具 | 工具名称 | 菜单路径 | 说明 | |---------|---------|------| -| **SO Manager** | `BaseGames → Tools → SO Manager` | 全项目 ScriptableObject 浏览器,支持类型/路径搜索 + Ping | -| **Event Bus Monitor** | `BaseGames → Tools → Event Bus Monitor` | 运行时事件派发监控(类型/侦听器数/触发次数实时显示) | -| **Create Event Channel Assets** | `BaseGames → Tools → Create Event Channel Assets` | 一键生成全局事件频道 SO(幂等,跳过已存在资产) | -| **GM Debug Tool** | `BaseGames → Tools → GM Debug Tool` | 运行时快速注入资源/切换形态/解锁技能(仅 PlayMode) | -| **Validate All ScriptableObjects** | `BaseGames → Tools → Validate All ScriptableObjects` | 扫描所有 `IValidatable` SO 并报告错误(构建前自动触发) | +| **Event Bus Monitor** | `BaseGames/Events/Event Bus Monitor` (Ctrl+Shift+E) | 运行时事件派发监控(类型/侦听器数/触发次数实时显示) | +| **Event Chain Viewer** | `BaseGames/Events/Event Chain Viewer` | 叙事事件链可视化,运行时显示完成/满足/等待状态 | +| **Create Event Channels** | `BaseGames/Events/Create Event Channels` | 一键生成全局事件频道 SO(幂等,跳过已存在资产) | +| **Reimport Event Channels** | `BaseGames/Events/Reimport Event Channels` | 重新导入/刷新全局事件频道 SO | -> **原则**:新增资产类型时,必须同步在对应编辑器工具中增加创建入口;严禁绕过工具手动在 Project 窗口 "Create" 并手动填写路径/命名,否则将导致 Addressables Rule Sync 工具误报分组或标签不一致。 +### 12.5 工具与维护 + +| 工具名称 | 菜单路径 | 说明 | +|---------|---------|------| +| **SO Manager** | `BaseGames/Tools/SO Manager` | 全项目 ScriptableObject 浏览器,支持类型/路径搜索 + Ping | +| **GM Debug Tool** | `BaseGames/Tools/GM Debug Tool` | 运行时快速注入资源/切换形态/解锁技能(仅 PlayMode) | +| **Validate All SOs** | `BaseGames/Tools/Validation/Validate All ScriptableObjects` | 扫描所有 `IValidatable` SO 并报告错误(构建前自动触发) | +| **Apply Script Order** | `BaseGames/Tools/Validation/Apply Script Execution Order Preset` | 将脚本执行顺序预设应用到项目 | +| **Validate Script Order** | `BaseGames/Tools/Validation/Validate Script Execution Order Preset` | 验证当前脚本执行顺序是否符合预设 | +| **Missing Scripts (Scene)** | `BaseGames/Tools/Maintenance/Missing Scripts/...` | 在场景/Prefab 中查找或清除 Missing Script 引用 | +| **Physics2D Layer Matrix** | `BaseGames/Tools/Maintenance/Physics2D Layer Matrix/...` | 检查或自动修复 Physics2D 层碰撞矩阵配置 | + +> **原则**:新增资产类型时,必须同步在对应编辑器工具中增加创建入口;严禁绕过工具手动在 Project 窗口 "Create" 并手动填写路径/命名,否则将导致 Addressables Rule Sync 工具误报分组或标签不一致。 \ No newline at end of file