Files
zeling_v2/Assets/_Game/Scripts/Editor/Modules/WeaponModule.cs
Joywayer bb3afd130f feat: Add SkillModule and WeaponModule for managing skills and weapons
- Implemented SkillModule to manage FormSkillSO assets with a detailed UI for editing and displaying skill properties.
- Implemented WeaponModule to manage WeaponSO assets with a detailed UI for editing and displaying weapon properties.
- Created AssetOperations class for centralized CRUD operations on ScriptableObject assets, including create, rename, delete, and clone functionalities.
- Added DetailHeader for displaying and renaming asset names in the UI.
- Introduced SoListPane for a reusable ScriptableObject list panel with search functionality and context menus.
- Added meta files for all new scripts to ensure proper asset management in Unity.
2026-05-21 07:09:53 +08:00

185 lines
6.6 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.Player;
namespace BaseGames.Editor.Modules
{
/// <summary>
/// DataHub 武器模块 —— 管理 WeaponSO 资产。
/// </summary>
public class WeaponModule : IDataModule
{
private const string Folder = "Assets/_Game/Data/Weapons";
private const string Prefix = "WPN_";
public string ModuleId => "weapon";
public string DisplayName => "武器";
public string IconName => "d_Sword Icon";
private SoListPane<WeaponSO> _listPane;
private DetailHeader _header;
private VisualElement _detailRoot;
private WeaponSO _selected;
public void Initialize()
{
_listPane = new SoListPane<WeaponSO>(
Folder, Prefix,
w => w.weaponType.ToString());
}
public void BuildListPane(VisualElement container, Action<UnityEngine.Object> 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);
insp.style.flexGrow = 1;
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;
}
}
}