using System; using UnityEditor; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; using BaseGames.Player; namespace BaseGames.Editor.Modules { /// /// DataHub 武器模块 —— 管理 WeaponSO 资产。 /// public class WeaponModule : IDataModule, IDataModuleOrdered { private const string Folder = "Assets/_Game/Data/Weapons"; private const string Prefix = "WPN_"; public string ModuleId => "weapon"; public string DisplayName => "武器"; public string IconName => null; public int DisplayOrder => 10; private SoListPane _listPane; private DetailHeader _header; private VisualElement _detailRoot; private WeaponSO _selected; public void Initialize() { _listPane = new SoListPane( Folder, Prefix, w => w.weaponType.ToString()); } public void BuildListPane(VisualElement container, Action onSelected) { _listPane.SelectionChanged = sel => { _selected = sel; onSelected?.Invoke(sel); }; container.Add(_listPane); _listPane.Refresh(); } public void BuildDetailPane(VisualElement container, UnityEngine.Object selected) { _selected = selected as WeaponSO; // Header(重命名) _header = new DetailHeader(); _header.SetAsset(_selected); _header.RenameRequested += OnRenameRequested; container.Add(_header); if (_selected == null) return; // Stats Card var statsCard = BuildStatsCard(_selected); container.Add(statsCard); // 操作按钮行 var toolbar = BuildActionBar(_selected); container.Add(toolbar); // 分隔线 container.Add(MakeDivider()); // Inspector var insp = new InspectorElement(_selected); container.Add(insp); } public void OnActivated() { _listPane?.Refresh(); } // ── 内部 ───────────────────────────────────────────────────────────── private void OnRenameRequested(string newName) { if (_selected == null) return; var (ok, err) = AssetOperations.Rename(_selected, newName); if (!ok) EditorUtility.DisplayDialog("重命名失败", err, "确定"); else { _header.SetAsset(_selected); _listPane.Invalidate(); } } private static VisualElement BuildStatsCard(WeaponSO w) { var card = new VisualElement(); card.style.flexDirection = FlexDirection.Row; card.style.flexWrap = Wrap.Wrap; card.style.paddingLeft = 12; card.style.paddingRight = 12; card.style.paddingTop = 8; card.style.paddingBottom = 8; card.style.marginBottom = 4; card.style.backgroundColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f, 0.08f)); card.style.borderBottomWidth = 1; card.style.borderBottomColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f, 0.2f)); AddStatChip(card, "类型", w.weaponType.ToString()); AddStatChip(card, "地面段数", (w.groundComboSteps?.Length ?? 0).ToString()); AddStatChip(card, "空中段数", (w.airComboSteps?.Length ?? 0).ToString()); AddStatChip(card, "ID", string.IsNullOrEmpty(w.weaponId) ? "-" : w.weaponId); return card; } private static void AddStatChip(VisualElement parent, string label, string value) { var chip = new VisualElement(); chip.style.flexDirection = FlexDirection.Row; chip.style.alignItems = Align.Center; chip.style.marginRight = 14; chip.style.marginBottom = 2; var lbl = new Label(label + ":"); lbl.style.opacity = 0.6f; lbl.style.fontSize = 11; lbl.style.marginRight = 3; chip.Add(lbl); var val = new Label(value); val.style.fontSize = 11; val.style.unityFontStyleAndWeight = UnityEngine.FontStyle.Bold; chip.Add(val); parent.Add(chip); } private VisualElement BuildActionBar(WeaponSO w) { var bar = new VisualElement(); bar.style.flexDirection = FlexDirection.Row; bar.style.paddingLeft = 12; bar.style.paddingRight = 12; bar.style.paddingTop = 6; bar.style.paddingBottom = 6; bar.style.flexWrap = Wrap.Wrap; var btnPing = new Button(() => { EditorGUIUtility.PingObject(w); Selection.activeObject = w; }) { text = "在 Project 中定位", tooltip = "在 Project 窗口高亮此资产" }; bar.Add(btnPing); var btnClone = new Button(() => { var clone = AssetOperations.Clone(w, Folder); if (clone != null) _listPane.Refresh(clone); }) { text = "克隆..." }; bar.Add(btnClone); var btnDel = new Button(() => { if (AssetOperations.Delete(w)) _listPane.Refresh(null); }) { text = "删除" }; btnDel.style.borderLeftColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f)); btnDel.style.borderRightColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f)); btnDel.style.borderTopColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f)); btnDel.style.borderBottomColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f)); btnDel.style.borderLeftWidth = 1; btnDel.style.borderRightWidth = 1; btnDel.style.borderTopWidth = 1; btnDel.style.borderBottomWidth = 1; btnDel.style.marginLeft = 8; bar.Add(btnDel); return bar; } private static VisualElement MakeDivider() { var d = new VisualElement(); d.style.height = 1; d.style.backgroundColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f, 0.2f)); return d; } } }