Files
zeling_v2/Assets/_Game/Scripts/Editor/Modules/CharmModule.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

212 lines
8.7 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;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using BaseGames.Equipment;
namespace BaseGames.Editor.Modules
{
/// <summary>
/// DataHub 护符模块 —— Tab 切换管理 CharmCatalogSO目录和 CharmSO护符资产。
/// </summary>
public class CharmModule : IDataModule
{
private const string CharmFolder = "Assets/_Game/Data/Progression/Charms";
private const string CatalogPrefix = "CHM_Catalog";
private const string CharmPrefix = "CHM_";
public string ModuleId => "charm";
public string DisplayName => "护符";
public string IconName => null;
private int _activeTab = 0; // 0 = 目录, 1 = 护符
private SoListPane<CharmCatalogSO> _catalogPane;
private SoListPane<CharmSO> _charmPane;
private Action<UnityEngine.Object> _onSelected;
private DetailHeader _header;
private CharmCatalogSO _selectedCatalog;
private CharmSO _selectedCharm;
public void Initialize()
{
_catalogPane = new SoListPane<CharmCatalogSO>(CharmFolder, CatalogPrefix);
_catalogPane.SelectionChanged = s => { _selectedCatalog = s; _onSelected?.Invoke(s); };
_charmPane = new SoListPane<CharmSO>(CharmFolder, CharmPrefix,
c => $"{c.notchCost}格");
_charmPane.SelectionChanged = s => { _selectedCharm = s; _onSelected?.Invoke(s); };
}
public void BuildListPane(VisualElement container, Action<UnityEngine.Object> onSelected)
{
_onSelected = onSelected;
container.style.flexDirection = FlexDirection.Column;
// Tab bar
var tabBar = new VisualElement();
tabBar.style.flexDirection = FlexDirection.Row;
tabBar.style.borderBottomWidth = 1;
tabBar.style.borderBottomColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f, 0.3f));
container.Add(tabBar);
var btnCatalog = BuildTabBtn("目录", 0, tabBar);
var btnCharms = BuildTabBtn("护符", 1, tabBar);
var listArea = new VisualElement();
listArea.style.flexGrow = 1;
container.Add(listArea);
var tabs = new[] { btnCatalog, btnCharms };
ShowTab(0, listArea, tabs);
btnCatalog.clicked += () => ShowTab(0, listArea, tabs);
btnCharms.clicked += () => ShowTab(1, listArea, tabs);
_catalogPane.Refresh();
_charmPane.Refresh();
}
public void BuildDetailPane(VisualElement container, UnityEngine.Object selected)
{
_header = new DetailHeader();
_header.SetAsset(selected);
_header.RenameRequested += name => OnRenameRequested(selected, name);
container.Add(_header);
if (selected == null) return;
if (selected is CharmCatalogSO catalog)
{
container.Add(BuildCatalogActionBar(catalog));
container.Add(SkillModule.MakeDivider());
container.Add(new InspectorElement(catalog));
}
else if (selected is CharmSO charm)
{
container.Add(BuildCharmCard(charm));
container.Add(BuildCharmActionBar(charm));
container.Add(SkillModule.MakeDivider());
container.Add(new InspectorElement(charm));
}
}
public void OnActivated()
{
_catalogPane?.Refresh();
_charmPane?.Refresh();
}
// ── Tab UI ────────────────────────────────────────────────────────────
private Button BuildTabBtn(string text, int tabIdx, VisualElement bar)
{
var btn = new Button { text = text };
btn.style.flexGrow = 1;
btn.style.paddingTop = 5;
btn.style.paddingBottom = 5;
btn.style.borderTopLeftRadius = 0;
btn.style.borderTopRightRadius = 0;
btn.style.borderBottomLeftRadius = 0;
btn.style.borderBottomRightRadius = 0;
btn.style.borderLeftWidth = 0;
btn.style.borderRightWidth = 0;
btn.style.borderTopWidth = 0;
btn.style.borderBottomWidth = 0;
btn.style.backgroundColor = new StyleColor(Color.clear);
btn.userData = tabIdx;
bar.Add(btn);
return btn;
}
private void ShowTab(int tab, VisualElement area, Button[] tabBtns)
{
_activeTab = tab;
area.Clear();
for (int i = 0; i < tabBtns.Length; i++)
{
if (i == tab)
{
tabBtns[i].style.borderBottomWidth = 2;
tabBtns[i].style.borderBottomColor = new StyleColor(new Color(0.4f, 0.65f, 1f, 1f));
tabBtns[i].style.opacity = 1f;
}
else
{
tabBtns[i].style.borderBottomWidth = 0;
tabBtns[i].style.opacity = 0.65f;
}
}
if (tab == 0) { _catalogPane.style.flexGrow = 1; area.Add(_catalogPane); }
else { _charmPane.style.flexGrow = 1; area.Add(_charmPane); }
}
// ── 重命名 ────────────────────────────────────────────────────────────
private void OnRenameRequested(UnityEngine.Object asset, string newName)
{
var (ok, err) = AssetOperations.Rename(asset, newName);
if (!ok) EditorUtility.DisplayDialog("重命名失败", err, "确定");
else
{
_header.SetAsset(asset);
if (_activeTab == 0) _catalogPane.Invalidate();
else _charmPane.Invalidate();
}
}
// ── CharmCatalogSO 详情 ───────────────────────────────────────────────
private VisualElement BuildCatalogActionBar(CharmCatalogSO catalog)
{
var bar = SkillModule.MakeActionBar();
new Button(() => { EditorGUIUtility.PingObject(catalog); Selection.activeObject = catalog; })
{ text = "定位" }.AlsoAddTo(bar);
return bar;
}
// ── CharmSO 详情 ──────────────────────────────────────────────────────
private static VisualElement BuildCharmCard(CharmSO c)
{
var card = SkillModule.MakeCard();
SkillModule.AddChip(card, "ID", string.IsNullOrEmpty(c.charmId) ? "-" : c.charmId);
SkillModule.AddChip(card, "格数", $"{c.notchCost}");
SkillModule.AddChip(card, "效果数", $"{c.effects?.Count ?? 0}");
if (c.isUnique)
SkillModule.AddChip(card, "限定", "唯一");
return card;
}
private VisualElement BuildCharmActionBar(CharmSO charm)
{
var bar = SkillModule.MakeActionBar();
new Button(() => { EditorGUIUtility.PingObject(charm); Selection.activeObject = charm; })
{ text = "定位" }.AlsoAddTo(bar);
new Button(() => { var c = AssetOperations.Clone(charm, CharmFolder); if (c != null) _charmPane.Refresh(c); })
{ text = "克隆..." }.AlsoAddTo(bar);
var del = new Button(() => { if (AssetOperations.Delete(charm)) _charmPane.Refresh(null); }) { text = "删除" };
ApplyDeleteStyle(del);
del.AlsoAddTo(bar);
return bar;
}
// ── 共用 ─────────────────────────────────────────────────────────────
private static void ApplyDeleteStyle(Button btn)
{
var c = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
btn.style.borderLeftColor = c;
btn.style.borderRightColor = c;
btn.style.borderTopColor = c;
btn.style.borderBottomColor = c;
btn.style.borderLeftWidth = 1;
btn.style.borderRightWidth = 1;
btn.style.borderTopWidth = 1;
btn.style.borderBottomWidth = 1;
btn.style.marginLeft = 8;
}
}
}