Files
zeling_v2/Assets/_Game/Scripts/Editor/Events/CreateEventChannelAssets.cs
Joywayer e879efaa89 Add InputDeviceIconSetSO configuration guide and related documentation
- Created a new markdown file detailing the configuration of InputDeviceIconSetSO.
- Included sections on system architecture, field explanations, image specifications, and complete workflow from setup to runtime.
- Documented the automatic device recognition logic and provided troubleshooting for common issues.
- Added references to relevant files and scripts for easier navigation.
2026-05-23 00:10:23 +08:00

221 lines
15 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 UnityEngine;
using UnityEditor;
using BaseGames.Core.Events;
using BaseGames.Combat;
using BaseGames.Combat.StatusEffects;
using BaseGames.Equipment;
using BaseGames.Parry;
using BaseGames.Player;
using BaseGames.Dialogue;
using BaseGames.Progression;
using System.IO;
namespace BaseGames.Editor
{
/// <summary>
/// Editor 工具:一键在 Assets/_Game/Data/Events/ 下生成所有全局事件频道 .asset 资产。
/// 菜单BaseGames → Tools → Create Event Channel Assets
/// 已存在的资产会自动跳过(幂等)。
/// </summary>
public static class CreateEventChannelAssets
{
private const string RootPath = "Assets/_Game/Data/Events";
[MenuItem("BaseGames/Events/Create Event Channels")]
public static void CreateAll()
{
// ── Core 原始类型频道 ──────────────────────────────────────────────
CreateAsset<VoidEventChannelSO> ("Core", "EVT_Void");
CreateAsset<BoolEventChannelSO> ("Core", "EVT_Bool");
CreateAsset<IntEventChannelSO> ("Core", "EVT_Int");
CreateAsset<FloatEventChannelSO> ("Core", "EVT_Float");
CreateAsset<StringEventChannelSO> ("Core", "EVT_String");
CreateAsset<Vector2EventChannelSO> ("Core", "EVT_Vector2");
CreateAsset<TransformEventChannelSO> ("Core", "EVT_Transform");
CreateAsset<GameStateEventChannelSO> ("Core", "EVT_GameStateChanged");
CreateAsset<SceneLoadRequestEventChannelSO>("Core", "EVT_SceneLoadRequest");
CreateAsset<StringEventChannelSO> ("Core", "EVT_SceneLoaded");
CreateAsset<VoidEventChannelSO> ("Core", "EVT_FadeInRequest");
CreateAsset<VoidEventChannelSO> ("Core", "EVT_FadeOutRequest");
CreateAsset<VoidEventChannelSO> ("Core", "EVT_SceneWorldStateRestored"); // 场景加载完毕、世界状态恢复后触发;场景物体在此订阅并应用存档状态,淡入前保证画面正确
// ── 难度 ──────────────────────────────────────────────────────────
CreateAsset<DifficultyChangedEventChannel>("Difficulty", "EVT_DifficultyChanged");
// ── 战斗 ──────────────────────────────────────────────────────────
CreateAsset<DamageInfoEventChannelSO> ("Combat", "EVT_DamageDealt");
CreateAsset<HitConfirmedEventChannelSO> ("Combat", "EVT_HitConfirmed");
CreateAsset<VoidEventChannelSO> ("Combat", "EVT_NailClash");
CreateAsset<VoidEventChannelSO> ("Combat", "EVT_PlayerDied");
CreateAsset<VoidEventChannelSO> ("Combat", "EVT_DeathScreenConfirmed");
CreateAsset<StringEventChannelSO> ("Combat", "EVT_EnemyDied");
CreateAsset<ParryInfoEventChannelSO> ("Combat", "EVT_ParrySuccess");
CreateAsset<VoidEventChannelSO> ("Combat", "EVT_PlayerRespawned");
CreateAsset<VoidEventChannelSO> ("Combat", "EVT_RespawnStarted");
CreateAsset<VoidEventChannelSO> ("Combat", "EVT_RespawnCompleted");
CreateAsset<VoidEventChannelSO> ("Combat", "EVT_CheckpointRespawn");
CreateAsset<StatusEffectEventChannelSO> ("Combat", "EVT_StatusEffectApplied");
CreateAsset<StatusEffectEventChannelSO> ("Combat", "EVT_StatusEffectExpired");
CreateAsset<VoidEventChannelSO> ("Combat", "EVT_ShieldBroken");
CreateAsset<VoidEventChannelSO> ("Combat", "EVT_ShieldRestored");
// ── Boss ──────────────────────────────────────────────────────────
CreateAsset<BossSkillEventChannelSO> ("Boss", "EVT_BossSkill");
CreateAsset<BossPhaseEventChannelSO> ("Boss", "EVT_BossPhase");
CreateAsset<BossPhaseEventChannelSO> ("Boss", "EVT_BossPhaseChanged");
CreateAsset<StringEventChannelSO> ("Boss", "EVT_BossDefeated");
CreateAsset<StatusEffectEventChannelSO> ("Boss", "EVT_StatusEffect");
CreateAsset<StringEventChannelSO> ("Boss", "EVT_BossFightStarted");
CreateAsset<BoolEventChannelSO> ("Boss", "EVT_BossFightEnded");
// ── 任务 ──────────────────────────────────────────────────────────
CreateAsset<QuestStateChangedEventChannel>("Quest", "EVT_QuestStateChanged");
CreateAsset<QuestObjectiveEventChannelSO> ("Quest", "EVT_QuestObjective");
// ── UI ────────────────────────────────────────────────────────────
CreateAsset<VoidEventChannelSO> ("UI", "EVT_PauseRequested");
CreateAsset<VoidEventChannelSO> ("UI", "EVT_PauseResumed");
CreateAsset<VoidEventChannelSO> ("UI", "EVT_FastTravelOpen");
CreateAsset<StringEventChannelSO> ("UI", "EVT_ShopOpen");
CreateAsset<VoidEventChannelSO> ("UI", "EVT_MapOpen");
CreateAsset<ColorblindModeEventChannelSO> ("UI", "EVT_ColorblindMode");
CreateAsset<BoolEventChannelSO> ("UI", "EVT_InputDeviceChanged");
CreateAsset<BoolEventChannelSO> ("UI", "EVT_SaveIndicatorVisible");
// ── 启动流程 / Splash ─────────────────────────────────────────────
CreateAsset<VoidEventChannelSO> ("UI/Splash", "EVT_SplashStartRequest");
CreateAsset<VoidEventChannelSO> ("UI/Splash", "EVT_SplashComplete");
// ── 启动流程 / Loading 画面 ───────────────────────────────────────
CreateAsset<VoidEventChannelSO> ("UI/Loading", "EVT_LoadingStarted");
CreateAsset<VoidEventChannelSO> ("UI/Loading", "EVT_LoadingComplete");
CreateAsset<FloatEventChannelSO> ("UI/Loading", "EVT_LoadingProgressUpdated");
CreateAsset<BoolEventChannelSO> ("UI/Loading", "EVT_LoadingOverlay");
// ── 启动流程 / 主菜单 ─────────────────────────────────────────────
CreateAsset<IntEventChannelSO> ("UI/MainMenu", "EVT_SlotConfirmed");
// ── World ─────────────────────────────────────────────────────────
CreateAsset<StringEventChannelSO> ("World", "EVT_SavePointActivated");
CreateAsset<VoidEventChannelSO> ("World", "EVT_CheckpointReached");
CreateAsset<StringEventChannelSO> ("World", "EVT_DoorOpened"); // 开门/交互机关(钥匙、机关等)触发自动存档
CreateAsset<StringEventChannelSO> ("World", "EVT_ItemPickup"); // 道具/收集品获取itemId
CreateAsset<StringEventChannelSO> ("World", "EVT_CollectiblePickup"); // 关键物品拾取护符、道具等触发存档AutoSaveService / QuestManager / EventChainManager 监听
CreateAsset<StringEventChannelSO> ("World", "EVT_CollectibleSaved"); // 持久化记录收集品collectibleId
CreateAsset<StringEventChannelSO> ("World", "EVT_RoomEntered"); // 玩家进入新房间roomId
CreateAsset<StringEventChannelSO> ("World", "EVT_RegionChanged"); // 玩家首次进入新区域regionId
CreateAsset<StringEventChannelSO> ("World", "EVT_RevealRegion"); // 触发地图区域揭露regionId
CreateAsset<StringEventChannelSO> ("World", "EVT_MapUpdated"); // 房间首次探索/标注时刷新roomIdMapManager 发布MapPanel 订阅
CreateAsset<StringEventChannelSO> ("World", "EVT_ChallengeCompleted"); // 挑战房间通关challengeId
CreateAsset<StringEventChannelSO> ("World", "EVT_ChallengeFailed"); // 挑战房间失败challengeId
CreateAsset<LiquidEventChannelSO> ("World", "EVT_LiquidEntered"); // 玩家进入液体区域
CreateAsset<LiquidEventChannelSO> ("World", "EVT_LiquidExited"); // 玩家离开液体区域
CreateAsset<BaseGames.World.WorldMarkerEventChannelSO>("World", "EVT_WorldMarkerActivated"); // 导航标记点激活(地图图标显示)
CreateAsset<BaseGames.World.WorldMarkerEventChannelSO>("World", "EVT_WorldMarkerDeactivated"); // 导航标记点失活(地图图标隐藏)
// ── 对话/商店 ─────────────────────────────────────────────────────
CreateAsset<ShopPurchaseEventChannelSO> ("Dialogue", "EVT_ShopPurchase");
CreateAsset<DialogueEventChannelSO> ("Dialogue", "EVT_DialogueStartRequest");
CreateAsset<VoidEventChannelSO> ("Dialogue", "EVT_DialogueEnded");
CreateAsset<VoidEventChannelSO> ("Dialogue", "EVT_ShopClosed");
// ── 玩家能力 ──────────────────────────────────────────────────────
CreateAsset<TransformEventChannelSO> ("Player", "EVT_PlayerSpawned");
CreateAsset<IntEventChannelSO> ("Player", "EVT_HPChanged");
CreateAsset<IntEventChannelSO> ("Player", "EVT_MaxHPChanged");
CreateAsset<IntEventChannelSO> ("Player", "EVT_SoulPowerChanged");
CreateAsset<IntEventChannelSO> ("Player", "EVT_SpiritPowerChanged");
CreateAsset<IntEventChannelSO> ("Player", "EVT_SpringChargesChanged");
CreateAsset<IntEventChannelSO> ("Player", "EVT_LingZhuChanged");
CreateAsset<AbilityTypeEventChannelSO> ("Player", "EVT_AbilityUnlocked");
CreateAsset<StringEventChannelSO> ("Player", "EVT_AbilityUnlockedStr");
CreateAsset<IntEventChannelSO> ("Player", "EVT_FormChanged");
CreateAsset<VoidEventChannelSO> ("Player", "EVT_SkillSetChanged");
// ── 音频 ──────────────────────────────────────────────────────────
CreateAsset<StringEventChannelSO> ("Audio", "EVT_BGMRequest");
CreateAsset<VoidEventChannelSO> ("Audio", "EVT_BGMStop");
// ── 进度/成就 ─────────────────────────────────────────────────────
CreateAsset<ToolUsedEventChannelSO> ("Progression", "EVT_ToolUsed");
CreateAsset<AchievementEventChannelSO> ("Progression", "EVT_AchievementUnlocked");
CreateAsset<StringEventChannelSO> ("Progression", "EVT_MaxHPContainerPickedUp");
CreateAsset<VoidEventChannelSO> ("Progression", "EVT_AchievementNotchGranted");
CreateAsset<CharmEventChannelSO> ("Progression", "EVT_CharmEquipped");
CreateAsset<CharmEventChannelSO> ("Progression", "EVT_CharmUnequipped");
CreateAsset<VoidEventChannelSO> ("Progression", "EVT_EquipmentChanged");
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("[CreateEventChannelAssets] 所有事件频道资产生成完毕。");
}
[MenuItem("BaseGames/Events/Reimport Event Channels")]
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<T>(string subfolder, string assetName) where T : ScriptableObject
{
string folderPath = $"{RootPath}/{subfolder}";
EnsureDirectory(folderPath);
string fullPath = $"{folderPath}/{assetName}.asset";
if (AssetDatabase.LoadAssetAtPath<T>(fullPath) != null)
{
Debug.Log($"[CreateEventChannelAssets] 已跳过(已存在): {fullPath}");
return;
}
// 存在但类型不匹配(如旧版残留),先删除再重建
if (AssetDatabase.LoadMainAssetAtPath(fullPath) != null)
{
AssetDatabase.DeleteAsset(fullPath);
Debug.Log($"[CreateEventChannelAssets] 已删除旧类型资产: {fullPath}");
}
T asset = ScriptableObject.CreateInstance<T>();
AssetDatabase.CreateAsset(asset, fullPath);
Debug.Log($"[CreateEventChannelAssets] 已创建: {fullPath}");
}
/// <summary>递归创建所有缺失的中间文件夹(使用 AssetDatabase API。</summary>
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;
}
}
}
}