Files
zeling_v2/Assets/_Game/Scripts/Editor/Events/CreateEventChannelAssets.cs
Joywayer d09bc95c3f Refactor event channels and update layer specifications
- Removed StatusEffectEventChannelSO and its associated meta file.
- Updated CreateEventChannelAssets to handle new shield-related events.
- Added CharmModule for managing charm assets in the DataHub.
- Introduced CharmEventChannelSO for charm equipped/unequipped events.
- Changed layer references from "Ground" to "Platform" in various scripts.
- Updated documentation to reflect changes in layer specifications.
- Created new event assets for ShieldBroken, ShieldRestored, StatusEffectApplied, and StatusEffectExpired.
2026-05-21 11:08:14 +08:00

216 lines
14 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<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_CollectibleSaved"); // 持久化记录收集品collectibleId
CreateAsset<StringEventChannelSO> ("World", "EVT_RoomEntered"); // 玩家进入新房间roomId
CreateAsset<StringEventChannelSO> ("World", "EVT_RegionChanged"); // 玩家首次进入新区域regionId
CreateAsset<StringEventChannelSO> ("World", "EVT_RevealRegion"); // 触发地图区域揭露regionId
CreateAsset<StringEventChannelSO> ("World", "EVT_ChallengeCompleted"); // 挑战房间通关challengeId
CreateAsset<StringEventChannelSO> ("World", "EVT_ChallengeFailed"); // 挑战房间失败challengeId
CreateAsset<LiquidEventChannelSO> ("World", "EVT_LiquidEntered"); // 玩家进入液体区域
CreateAsset<LiquidEventChannelSO> ("World", "EVT_LiquidExited"); // 玩家离开液体区域
// ── 对话/商店 ─────────────────────────────────────────────────────
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;
}
}
}
}