using UnityEngine; using UnityEditor; using BaseGames.Core.Events; using BaseGames.Combat; using BaseGames.Player; using BaseGames.Dialogue; using BaseGames.Progression; using System.IO; namespace BaseGames.Editor { /// /// Editor 工具:一键在 Assets/_Game/Data/Events/ 下生成所有全局事件频道 .asset 资产。 /// 菜单:BaseGames → Tools → Create Event Channel Assets /// 已存在的资产会自动跳过(幂等)。 /// public static class CreateEventChannelAssets { private const string RootPath = "Assets/_Game/Data/Events"; [MenuItem("BaseGames/Tools/Create Event Channel Assets")] public static void CreateAll() { // ── Core 原始类型频道 ────────────────────────────────────────────── CreateAsset ("Core", "EVT_Void"); CreateAsset ("Core", "EVT_Bool"); CreateAsset ("Core", "EVT_Int"); CreateAsset ("Core", "EVT_Float"); CreateAsset ("Core", "EVT_String"); CreateAsset ("Core", "EVT_Vector2"); CreateAsset ("Core", "EVT_Transform"); CreateAsset ("Core", "EVT_GameState"); CreateAsset ("Core", "EVT_GameStateChanged"); CreateAsset("Core", "EVT_SceneLoadRequest"); CreateAsset ("Core", "EVT_SceneLoaded"); CreateAsset ("Core", "EVT_FadeInRequest"); CreateAsset ("Core", "EVT_FadeOutRequest"); // ── 难度 ────────────────────────────────────────────────────────── CreateAsset("Difficulty", "EVT_DifficultyChanged"); // ── 战斗 ────────────────────────────────────────────────────────── CreateAsset ("Combat", "EVT_DamageDealt"); CreateAsset ("Combat", "EVT_HitConfirmed"); CreateAsset ("Combat", "EVT_PlayerDied"); CreateAsset ("Combat", "EVT_DeathScreenConfirmed"); CreateAsset ("Combat", "EVT_EnemyDied"); CreateAsset ("Combat", "EVT_ParrySuccess"); CreateAsset ("Combat", "EVT_PlayerRespawn"); CreateAsset ("Combat", "EVT_PlayerRespawned"); CreateAsset ("Combat", "EVT_RespawnStarted"); CreateAsset ("Combat", "EVT_RespawnCompleted"); CreateAsset ("Combat", "EVT_CheckpointRespawn"); // ── Boss ────────────────────────────────────────────────────────── CreateAsset ("Boss", "EVT_BossSkill"); CreateAsset ("Boss", "EVT_BossPhase"); CreateAsset ("Boss", "EVT_StatusEffect"); CreateAsset ("Boss", "EVT_BossFightStarted"); CreateAsset ("Boss", "EVT_BossFightEnded"); // ── 任务 ────────────────────────────────────────────────────────── CreateAsset("Quest", "EVT_QuestStateChanged"); CreateAsset ("Quest", "EVT_QuestObjective"); // ── UI ──────────────────────────────────────────────────────────── CreateAsset ("UI", "EVT_PauseRequested"); CreateAsset ("UI", "EVT_PauseResumed"); CreateAsset ("UI", "EVT_FastTravelOpen"); CreateAsset ("UI", "EVT_ShopOpen"); CreateAsset ("UI", "EVT_MapOpen"); CreateAsset ("UI", "EVT_ColorblindMode"); // ── World ───────────────────────────────────────────────────────── CreateAsset ("World", "EVT_SavePointActivated"); CreateAsset ("World", "EVT_CheckpointReached"); CreateAsset ("World", "EVT_DoorOpened"); // 开门/交互机关(钥匙、机关等)触发自动存档 // ── 对话/商店 ───────────────────────────────────────────────────── CreateAsset ("Dialogue", "EVT_ShopPurchase"); CreateAsset ("Dialogue", "EVT_DialogueStartRequest"); CreateAsset ("Dialogue", "EVT_DialogueEnded"); // ── 玩家能力 ────────────────────────────────────────────────────── CreateAsset ("Player", "EVT_PlayerSpawned"); CreateAsset ("Player", "EVT_HPChanged"); CreateAsset ("Player", "EVT_MaxHPChanged"); CreateAsset ("Player", "EVT_SoulPowerChanged"); CreateAsset ("Player", "EVT_SpiritPowerChanged"); CreateAsset ("Player", "EVT_SpringChargesChanged"); CreateAsset ("Player", "EVT_LingZhuChanged"); CreateAsset ("Player", "EVT_AbilityUnlocked"); CreateAsset ("Player", "EVT_AbilityUnlockedStr"); // ── 音频 ────────────────────────────────────────────────────────── CreateAsset ("Audio", "EVT_BGMRequest"); CreateAsset ("Audio", "EVT_BGMStop"); // ── 进度/成就 ───────────────────────────────────────────────────── CreateAsset ("Progression", "EVT_ToolUsed"); CreateAsset ("Progression", "EVT_AchievementUnlocked"); CreateAsset ("Progression", "EVT_MaxHPContainerPickedUp"); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Debug.Log("[CreateEventChannelAssets] 所有事件频道资产生成完毕。"); } [MenuItem("BaseGames/Tools/Reimport Event Channel Assets")] public static void ReimportAllEventAssets() { if (!AssetDatabase.IsValidFolder(RootPath)) { Debug.LogWarning($"[CreateEventChannelAssets] 未找到目录: {RootPath}"); return; } string absoluteRoot = Path.Combine(Directory.GetCurrentDirectory(), RootPath); string[] files = Directory.GetFiles(absoluteRoot, "*.asset", SearchOption.AllDirectories); int count = 0; foreach (string file in files) { string relativePath = "Assets" + file.Replace('\\', '/').Substring(Directory.GetCurrentDirectory().Length); AssetDatabase.ImportAsset(relativePath, ImportAssetOptions.ForceUpdate); count++; } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Debug.Log($"[CreateEventChannelAssets] 已重导入 {count} 个事件资产。"); } private static void CreateAsset(string subfolder, string assetName) where T : ScriptableObject { string folderPath = $"{RootPath}/{subfolder}"; EnsureDirectory(folderPath); string fullPath = $"{folderPath}/{assetName}.asset"; if (AssetDatabase.LoadAssetAtPath(fullPath) != null) { Debug.Log($"[CreateEventChannelAssets] 已跳过(已存在): {fullPath}"); return; } T asset = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(asset, fullPath); Debug.Log($"[CreateEventChannelAssets] 已创建: {fullPath}"); } /// 递归创建所有缺失的中间文件夹(使用 AssetDatabase API)。 private static void EnsureDirectory(string path) { if (AssetDatabase.IsValidFolder(path)) return; string[] parts = path.Split('/'); string current = parts[0]; for (int i = 1; i < parts.Length; i++) { string next = $"{current}/{parts[i]}"; if (!AssetDatabase.IsValidFolder(next)) AssetDatabase.CreateFolder(current, parts[i]); current = next; } } } }