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.
This commit is contained in:
212
Assets/_Game/Scripts/Editor/Modules/BossSkillModule.cs
Normal file
212
Assets/_Game/Scripts/Editor/Modules/BossSkillModule.cs
Normal file
@@ -0,0 +1,212 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using BaseGames.Boss;
|
||||
|
||||
namespace BaseGames.Editor.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// DataHub Boss技能模块 —— Tab 切换管理 BossSkillSO 和 SkillSequenceSO。
|
||||
/// </summary>
|
||||
public class BossSkillModule : IDataModule
|
||||
{
|
||||
private const string SkillFolder = "Assets/_Game/Data/Boss/Skills";
|
||||
private const string SeqFolder = "Assets/_Game/Data/Boss/Sequences";
|
||||
|
||||
public string ModuleId => "boss";
|
||||
public string DisplayName => "Boss技能";
|
||||
public string IconName => "d_SkinnedMeshRenderer Icon";
|
||||
|
||||
private int _activeTab = 0;
|
||||
|
||||
private SoListPane<BossSkillSO> _skillPane;
|
||||
private SoListPane<SkillSequenceSO> _seqPane;
|
||||
private Action<UnityEngine.Object> _onSelected;
|
||||
|
||||
private DetailHeader _header;
|
||||
private BossSkillSO _selectedSkill;
|
||||
private SkillSequenceSO _selectedSeq;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_skillPane = new SoListPane<BossSkillSO>(
|
||||
SkillFolder, "ABL_Boss_",
|
||||
s => s.category.ToString());
|
||||
_skillPane.SelectionChanged = s => { _selectedSkill = s; _onSelected?.Invoke(s); };
|
||||
|
||||
_seqPane = new SoListPane<SkillSequenceSO>(SeqFolder, "ABL_Seq_");
|
||||
_seqPane.SelectionChanged = s => { _selectedSeq = 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 btnSkill = BuildTabBtn("技能 (Skill)", 0, tabBar);
|
||||
var btnSeq = BuildTabBtn("序列 (Seq)", 1, tabBar);
|
||||
|
||||
var listArea = new VisualElement();
|
||||
listArea.style.flexGrow = 1;
|
||||
container.Add(listArea);
|
||||
|
||||
ShowTab(0, listArea, new[] { btnSkill, btnSeq });
|
||||
btnSkill.clicked += () => ShowTab(0, listArea, new[] { btnSkill, btnSeq });
|
||||
btnSeq.clicked += () => ShowTab(1, listArea, new[] { btnSkill, btnSeq });
|
||||
|
||||
_skillPane.Refresh();
|
||||
_seqPane.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 BossSkillSO skill)
|
||||
{
|
||||
container.Add(BuildSkillCard(skill));
|
||||
container.Add(BuildActionBar(skill, SkillFolder, _skillPane));
|
||||
container.Add(SkillModule.MakeDivider());
|
||||
var insp = new InspectorElement(skill);
|
||||
insp.style.flexGrow = 1;
|
||||
container.Add(insp);
|
||||
}
|
||||
else if (selected is SkillSequenceSO seq)
|
||||
{
|
||||
container.Add(BuildSeqCard(seq));
|
||||
container.Add(BuildActionBar(seq, SeqFolder, _seqPane));
|
||||
container.Add(SkillModule.MakeDivider());
|
||||
var insp = new InspectorElement(seq);
|
||||
insp.style.flexGrow = 1;
|
||||
container.Add(insp);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnActivated()
|
||||
{
|
||||
_skillPane?.Refresh();
|
||||
_seqPane?.Refresh();
|
||||
}
|
||||
|
||||
// ── 内部 ─────────────────────────────────────────────────────────────
|
||||
|
||||
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) { _skillPane.style.flexGrow = 1; area.Add(_skillPane); }
|
||||
else { _seqPane.style.flexGrow = 1; area.Add(_seqPane); }
|
||||
}
|
||||
|
||||
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) _skillPane.Invalidate();
|
||||
else _seqPane.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private static VisualElement BuildSkillCard(BossSkillSO s)
|
||||
{
|
||||
var card = SkillModule.MakeCard();
|
||||
SkillModule.AddChip(card, "分类", s.category.ToString());
|
||||
SkillModule.AddChip(card, "类型", s.skillType.ToString());
|
||||
SkillModule.AddChip(card, "模式数", (s.attackPatterns?.Length ?? 0).ToString());
|
||||
SkillModule.AddChip(card, "弱点窗口", (s.vulnerabilityWindows?.Length ?? 0).ToString());
|
||||
if (!string.IsNullOrEmpty(s.skillId))
|
||||
SkillModule.AddChip(card, "ID", s.skillId);
|
||||
return card;
|
||||
}
|
||||
|
||||
private static VisualElement BuildSeqCard(SkillSequenceSO s)
|
||||
{
|
||||
var card = SkillModule.MakeCard();
|
||||
SkillModule.AddChip(card, "步骤数", (s.steps?.Length ?? 0).ToString());
|
||||
SkillModule.AddChip(card, "循环", s.RepeatIfPlayerInRange ? "是" : "否");
|
||||
SkillModule.AddChip(card, "最大循环次数", s.MaxRepeatCount.ToString());
|
||||
return card;
|
||||
}
|
||||
|
||||
private VisualElement BuildActionBar<T>(T asset, string folder, SoListPane<T> pane)
|
||||
where T : ScriptableObject
|
||||
{
|
||||
var bar = SkillModule.MakeActionBar();
|
||||
new Button(() => { EditorGUIUtility.PingObject(asset); Selection.activeObject = asset; })
|
||||
{ text = "定位" }.AlsoAddTo(bar);
|
||||
new Button(() =>
|
||||
{
|
||||
var c = AssetOperations.Clone(asset, folder);
|
||||
if (c != null) pane.Refresh(c);
|
||||
}) { text = "克隆..." }.AlsoAddTo(bar);
|
||||
var del = new Button(() =>
|
||||
{
|
||||
if (AssetOperations.Delete(asset)) pane.Refresh(null);
|
||||
}) { text = "删除" };
|
||||
del.style.borderLeftColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderRightColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderTopColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderBottomColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderLeftWidth = 1;
|
||||
del.style.borderRightWidth = 1;
|
||||
del.style.borderTopWidth = 1;
|
||||
del.style.borderBottomWidth = 1;
|
||||
del.style.marginLeft = 8;
|
||||
del.AlsoAddTo(bar);
|
||||
return bar;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/_Game/Scripts/Editor/Modules/BossSkillModule.cs.meta
Normal file
11
Assets/_Game/Scripts/Editor/Modules/BossSkillModule.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0d0425e529293e469da3762fe3bf8f0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
207
Assets/_Game/Scripts/Editor/Modules/EnemyModule.cs
Normal file
207
Assets/_Game/Scripts/Editor/Modules/EnemyModule.cs
Normal file
@@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using BaseGames.Enemies;
|
||||
|
||||
namespace BaseGames.Editor.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// DataHub 敌人模块 —— Tab 切换管理 EnemyStatsSO 和 LootTableSO。
|
||||
/// </summary>
|
||||
public class EnemyModule : IDataModule
|
||||
{
|
||||
private const string StatsFolder = "Assets/_Game/Data/Enemies/Stats";
|
||||
private const string LootFolder = "Assets/_Game/Data/Enemies/Loot";
|
||||
|
||||
public string ModuleId => "enemy";
|
||||
public string DisplayName => "敌人";
|
||||
public string IconName => "d_Avatar Icon";
|
||||
|
||||
private int _activeTab = 0; // 0=Stats, 1=Loot
|
||||
|
||||
private SoListPane<EnemyStatsSO> _statsPane;
|
||||
private SoListPane<LootTableSO> _lootPane;
|
||||
private VisualElement _listContainer;
|
||||
private Action<UnityEngine.Object> _onSelected;
|
||||
|
||||
private DetailHeader _header;
|
||||
private EnemyStatsSO _selectedStats;
|
||||
private LootTableSO _selectedLoot;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_statsPane = new SoListPane<EnemyStatsSO>(StatsFolder, "ENM_");
|
||||
_statsPane.SelectionChanged = s => { _selectedStats = s; _onSelected?.Invoke(s); };
|
||||
|
||||
_lootPane = new SoListPane<LootTableSO>(LootFolder, "ENM_Loot_");
|
||||
_lootPane.SelectionChanged = l => { _selectedLoot = l; _onSelected?.Invoke(l); };
|
||||
}
|
||||
|
||||
public void BuildListPane(VisualElement container, Action<UnityEngine.Object> onSelected)
|
||||
{
|
||||
_onSelected = onSelected;
|
||||
_listContainer = container;
|
||||
|
||||
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 btnStats = BuildTabBtn("属性 (Stats)", 0, tabBar);
|
||||
var btnLoot = BuildTabBtn("掉落 (Loot)", 1, tabBar);
|
||||
|
||||
// 列表区域占位
|
||||
var listArea = new VisualElement();
|
||||
listArea.style.flexGrow = 1;
|
||||
container.Add(listArea);
|
||||
|
||||
ShowTab(0, listArea, new[] { btnStats, btnLoot });
|
||||
|
||||
btnStats.clicked += () => ShowTab(0, listArea, new[] { btnStats, btnLoot });
|
||||
btnLoot.clicked += () => ShowTab(1, listArea, new[] { btnStats, btnLoot });
|
||||
|
||||
_statsPane.Refresh();
|
||||
_lootPane.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 EnemyStatsSO stats)
|
||||
{
|
||||
container.Add(BuildStatsCard(stats));
|
||||
container.Add(BuildActionBar(stats, StatsFolder, _statsPane));
|
||||
container.Add(SkillModule.MakeDivider());
|
||||
var insp = new InspectorElement(stats);
|
||||
insp.style.flexGrow = 1;
|
||||
container.Add(insp);
|
||||
}
|
||||
else if (selected is LootTableSO loot)
|
||||
{
|
||||
container.Add(BuildLootCard(loot));
|
||||
container.Add(BuildActionBar(loot, LootFolder, _lootPane));
|
||||
container.Add(SkillModule.MakeDivider());
|
||||
var insp = new InspectorElement(loot);
|
||||
insp.style.flexGrow = 1;
|
||||
container.Add(insp);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnActivated()
|
||||
{
|
||||
_statsPane?.Refresh();
|
||||
_lootPane?.Refresh();
|
||||
}
|
||||
|
||||
// ── 内部 ─────────────────────────────────────────────────────────────
|
||||
|
||||
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) { _statsPane.style.flexGrow = 1; area.Add(_statsPane); }
|
||||
else { _lootPane.style.flexGrow = 1; area.Add(_lootPane); }
|
||||
}
|
||||
|
||||
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) _statsPane.Invalidate();
|
||||
else _lootPane.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private static VisualElement BuildStatsCard(EnemyStatsSO s)
|
||||
{
|
||||
var card = SkillModule.MakeCard();
|
||||
SkillModule.AddChip(card, "HP", s.MaxHP.ToString());
|
||||
SkillModule.AddChip(card, "防御", s.Defense.ToString());
|
||||
SkillModule.AddChip(card, "移速", $"{s.WalkSpeed}/{s.RunSpeed}");
|
||||
SkillModule.AddChip(card, "攻击", s.AttackDamage.ToString());
|
||||
SkillModule.AddChip(card, "感知", $"{s.DetectRange}m");
|
||||
return card;
|
||||
}
|
||||
|
||||
private static VisualElement BuildLootCard(LootTableSO l)
|
||||
{
|
||||
var card = SkillModule.MakeCard();
|
||||
SkillModule.AddChip(card, "掉落项", (l.Entries?.Length ?? 0).ToString());
|
||||
SkillModule.AddChip(card, "灵珠保底", $"{l.GuaranteedLingZhuMin}-{l.GuaranteedLingZhuMax}");
|
||||
return card;
|
||||
}
|
||||
|
||||
private VisualElement BuildActionBar<T>(T asset, string folder, SoListPane<T> pane)
|
||||
where T : ScriptableObject
|
||||
{
|
||||
var bar = SkillModule.MakeActionBar();
|
||||
new Button(() => { EditorGUIUtility.PingObject(asset); Selection.activeObject = asset; })
|
||||
{ text = "定位" }.AlsoAddTo(bar);
|
||||
new Button(() => { var c = AssetOperations.Clone(asset, folder); if (c != null) pane.Refresh(c); })
|
||||
{ text = "克隆..." }.AlsoAddTo(bar);
|
||||
var del = new Button(() => { if (AssetOperations.Delete(asset)) pane.Refresh(null); }) { text = "删除" };
|
||||
del.style.borderLeftColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderRightColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderTopColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderBottomColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderLeftWidth = 1;
|
||||
del.style.borderRightWidth = 1;
|
||||
del.style.borderTopWidth = 1;
|
||||
del.style.borderBottomWidth = 1;
|
||||
del.style.marginLeft = 8;
|
||||
del.AlsoAddTo(bar);
|
||||
return bar;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/_Game/Scripts/Editor/Modules/EnemyModule.cs.meta
Normal file
11
Assets/_Game/Scripts/Editor/Modules/EnemyModule.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32772b7d7bbc5824889620b773c352a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
209
Assets/_Game/Scripts/Editor/Modules/FormModule.cs
Normal file
209
Assets/_Game/Scripts/Editor/Modules/FormModule.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using BaseGames.Player;
|
||||
|
||||
namespace BaseGames.Editor.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// DataHub 形态模块 —— 管理 FormConfigSO(含三列 FormSO 预览)和 FormSO 资产。
|
||||
/// </summary>
|
||||
public class FormModule : IDataModule
|
||||
{
|
||||
private const string ConfigFolder = "Assets/_Game/Data/Player/Forms";
|
||||
private const string FormFolder = "Assets/_Game/Data/Player/Forms";
|
||||
|
||||
public string ModuleId => "form";
|
||||
public string DisplayName => "形态";
|
||||
public string IconName => "d_AvatarPivot";
|
||||
|
||||
private SoListPane<FormConfigSO> _listPane;
|
||||
private DetailHeader _header;
|
||||
private FormConfigSO _selected;
|
||||
|
||||
private static readonly (FormType type, string label, Color accent)[] FormDefs =
|
||||
{
|
||||
(FormType.TianHun, "天魂", new Color(0.40f, 0.70f, 1.00f)),
|
||||
(FormType.DiHun, "地魂", new Color(0.85f, 0.55f, 0.20f)),
|
||||
(FormType.MingHun, "命魂", new Color(0.70f, 0.25f, 0.75f)),
|
||||
};
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_listPane = new SoListPane<FormConfigSO>(ConfigFolder, "PLY_FormConfig_");
|
||||
}
|
||||
|
||||
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 FormConfigSO;
|
||||
|
||||
_header = new DetailHeader();
|
||||
_header.SetAsset(_selected);
|
||||
_header.RenameRequested += OnRenameRequested;
|
||||
container.Add(_header);
|
||||
|
||||
if (_selected == null) return;
|
||||
|
||||
// 操作按钮
|
||||
container.Add(BuildActionBar(_selected));
|
||||
container.Add(SkillModule.MakeDivider());
|
||||
|
||||
// 三列形态网格
|
||||
var grid = BuildFormGrid(_selected);
|
||||
container.Add(grid);
|
||||
|
||||
container.Add(SkillModule.MakeDivider());
|
||||
|
||||
// Raw 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 VisualElement BuildFormGrid(FormConfigSO config)
|
||||
{
|
||||
var grid = new VisualElement();
|
||||
grid.style.flexDirection = FlexDirection.Row;
|
||||
grid.style.paddingLeft = 8;
|
||||
grid.style.paddingRight = 8;
|
||||
grid.style.paddingTop = 8;
|
||||
grid.style.paddingBottom = 8;
|
||||
|
||||
for (int i = 0; i < FormDefs.Length; i++)
|
||||
{
|
||||
var (ft, label, accent) = FormDefs[i];
|
||||
var col = BuildFormColumn(config, ft, label, accent);
|
||||
if (i < 2) col.style.marginRight = 8;
|
||||
grid.Add(col);
|
||||
}
|
||||
return grid;
|
||||
}
|
||||
|
||||
private static VisualElement BuildFormColumn(
|
||||
FormConfigSO config, FormType ft, string label, Color accent)
|
||||
{
|
||||
var col = new VisualElement();
|
||||
col.style.flexGrow = 1;
|
||||
col.style.borderTopWidth = 2;
|
||||
col.style.borderTopColor = new StyleColor(accent);
|
||||
col.style.borderLeftWidth = 1;
|
||||
col.style.borderRightWidth = 1;
|
||||
col.style.borderBottomWidth = 1;
|
||||
col.style.borderLeftColor = new StyleColor(new Color(accent.r, accent.g, accent.b, 0.35f));
|
||||
col.style.borderRightColor = new StyleColor(new Color(accent.r, accent.g, accent.b, 0.35f));
|
||||
col.style.borderBottomColor = new StyleColor(new Color(accent.r, accent.g, accent.b, 0.35f));
|
||||
col.style.borderTopLeftRadius = 4;
|
||||
col.style.borderTopRightRadius = 4;
|
||||
col.style.borderBottomLeftRadius = 4;
|
||||
col.style.borderBottomRightRadius = 4;
|
||||
col.style.paddingLeft = 8;
|
||||
col.style.paddingRight = 8;
|
||||
col.style.paddingTop = 8;
|
||||
col.style.paddingBottom = 8;
|
||||
|
||||
// 标题行
|
||||
var titleRow = new VisualElement();
|
||||
titleRow.style.flexDirection = FlexDirection.Row;
|
||||
titleRow.style.alignItems = Align.Center;
|
||||
titleRow.style.marginBottom = 6;
|
||||
|
||||
var dot = new VisualElement();
|
||||
dot.style.width = 10;
|
||||
dot.style.height = 10;
|
||||
dot.style.borderTopLeftRadius = 5;
|
||||
dot.style.borderTopRightRadius = 5;
|
||||
dot.style.borderBottomLeftRadius = 5;
|
||||
dot.style.borderBottomRightRadius = 5;
|
||||
dot.style.backgroundColor = new StyleColor(accent);
|
||||
dot.style.marginRight = 6;
|
||||
titleRow.Add(dot);
|
||||
titleRow.Add(new Label(label) { style = { unityFontStyleAndWeight = UnityEngine.FontStyle.Bold } });
|
||||
col.Add(titleRow);
|
||||
|
||||
// FormSO 引用
|
||||
FormSO current = config.GetFormByType(ft);
|
||||
var formField = new ObjectField("FormSO") { objectType = typeof(FormSO), value = current };
|
||||
formField.RegisterValueChangedCallback(e =>
|
||||
{
|
||||
var newForm = e.newValue as FormSO;
|
||||
SetFormByType(config, ft, newForm);
|
||||
});
|
||||
col.Add(formField);
|
||||
|
||||
// 武器只读预览
|
||||
var wpnField = new ObjectField("默认武器") { objectType = typeof(WeaponSO), value = current?.defaultWeapon };
|
||||
wpnField.SetEnabled(false);
|
||||
formField.RegisterValueChangedCallback(e =>
|
||||
wpnField.value = (e.newValue as FormSO)?.defaultWeapon);
|
||||
col.Add(wpnField);
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
private static void SetFormByType(FormConfigSO config, FormType ft, FormSO form)
|
||||
{
|
||||
Undo.RecordObject(config, "Set FormSO");
|
||||
if (config.forms == null || config.forms.Length < 3)
|
||||
{
|
||||
var newArr = new FormSO[3];
|
||||
if (config.forms != null)
|
||||
Array.Copy(config.forms, newArr, Math.Min(config.forms.Length, 3));
|
||||
config.forms = newArr;
|
||||
}
|
||||
config.forms[(int)ft] = form;
|
||||
EditorUtility.SetDirty(config);
|
||||
}
|
||||
|
||||
private VisualElement BuildActionBar(FormConfigSO config)
|
||||
{
|
||||
var bar = SkillModule.MakeActionBar();
|
||||
new Button(() => { EditorGUIUtility.PingObject(config); Selection.activeObject = config; })
|
||||
{ text = "定位" }.AlsoAddTo(bar);
|
||||
new Button(() =>
|
||||
{
|
||||
var c = AssetOperations.Clone(config, ConfigFolder);
|
||||
if (c != null) _listPane.Refresh(c);
|
||||
}) { text = "克隆..." }.AlsoAddTo(bar);
|
||||
var del = new Button(() =>
|
||||
{
|
||||
if (AssetOperations.Delete(config)) _listPane.Refresh(null);
|
||||
}) { text = "删除" };
|
||||
del.style.borderLeftColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderRightColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderTopColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderBottomColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderLeftWidth = 1;
|
||||
del.style.borderRightWidth = 1;
|
||||
del.style.borderTopWidth = 1;
|
||||
del.style.borderBottomWidth = 1;
|
||||
del.style.marginLeft = 8;
|
||||
del.AlsoAddTo(bar);
|
||||
return bar;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/_Game/Scripts/Editor/Modules/FormModule.cs.meta
Normal file
11
Assets/_Game/Scripts/Editor/Modules/FormModule.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa270e8dd563fbc429bdb342988b9a54
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
187
Assets/_Game/Scripts/Editor/Modules/SkillModule.cs
Normal file
187
Assets/_Game/Scripts/Editor/Modules/SkillModule.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using BaseGames.Skills;
|
||||
|
||||
namespace BaseGames.Editor.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// DataHub 技能模块 —— 管理 FormSkillSO 资产。
|
||||
/// </summary>
|
||||
public class SkillModule : IDataModule
|
||||
{
|
||||
private const string Folder = "Assets/_Game/Data/Skills";
|
||||
private const string Prefix = "SKL_";
|
||||
|
||||
public string ModuleId => "skill";
|
||||
public string DisplayName => "技能";
|
||||
public string IconName => "d_Lighting Icon";
|
||||
|
||||
private SoListPane<FormSkillSO> _listPane;
|
||||
private DetailHeader _header;
|
||||
private FormSkillSO _selected;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_listPane = new SoListPane<FormSkillSO>(
|
||||
Folder, Prefix,
|
||||
s => s.resourceType.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 FormSkillSO;
|
||||
|
||||
_header = new DetailHeader();
|
||||
_header.SetAsset(_selected);
|
||||
_header.RenameRequested += OnRenameRequested;
|
||||
container.Add(_header);
|
||||
|
||||
if (_selected == null) return;
|
||||
|
||||
// Stats Card
|
||||
var card = BuildStatsCard(_selected);
|
||||
container.Add(card);
|
||||
|
||||
// 操作按钮
|
||||
container.Add(BuildActionBar(_selected));
|
||||
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(FormSkillSO s)
|
||||
{
|
||||
var card = MakeCard();
|
||||
AddChip(card, "效果类型", s.effectType.ToString());
|
||||
AddChip(card, "资源类型", s.resourceType.ToString());
|
||||
AddChip(card, "冷却", $"{s.cooldown:F1}s");
|
||||
AddChip(card, "消耗", s.baseCost.ToString());
|
||||
if (!string.IsNullOrEmpty(s.skillId))
|
||||
AddChip(card, "ID", s.skillId);
|
||||
return card;
|
||||
}
|
||||
|
||||
private VisualElement BuildActionBar(FormSkillSO s)
|
||||
{
|
||||
var bar = MakeActionBar();
|
||||
|
||||
new Button(() => { EditorGUIUtility.PingObject(s); Selection.activeObject = s; })
|
||||
{ text = "定位" }.AlsoAddTo(bar);
|
||||
|
||||
new Button(() => { var c = AssetOperations.Clone(s, Folder); if (c != null) _listPane.Refresh(c); })
|
||||
{ text = "克隆..." }.AlsoAddTo(bar);
|
||||
|
||||
var del = new Button(() => { if (AssetOperations.Delete(s)) _listPane.Refresh(null); }) { text = "删除" };
|
||||
del.style.borderLeftColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderRightColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderTopColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderBottomColor = new StyleColor(new Color(0.8f, 0.3f, 0.3f, 0.6f));
|
||||
del.style.borderLeftWidth = 1;
|
||||
del.style.borderRightWidth = 1;
|
||||
del.style.borderTopWidth = 1;
|
||||
del.style.borderBottomWidth = 1;
|
||||
del.style.marginLeft = 8;
|
||||
del.AlsoAddTo(bar);
|
||||
|
||||
return bar;
|
||||
}
|
||||
|
||||
// ── 共享构建辅助 ─────────────────────────────────────────────────────
|
||||
|
||||
internal static VisualElement MakeCard()
|
||||
{
|
||||
var c = new VisualElement();
|
||||
c.style.flexDirection = FlexDirection.Row;
|
||||
c.style.flexWrap = Wrap.Wrap;
|
||||
c.style.paddingLeft = 12;
|
||||
c.style.paddingRight = 12;
|
||||
c.style.paddingTop = 8;
|
||||
c.style.paddingBottom = 8;
|
||||
c.style.marginBottom = 4;
|
||||
c.style.backgroundColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f, 0.08f));
|
||||
c.style.borderBottomWidth = 1;
|
||||
c.style.borderBottomColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f, 0.2f));
|
||||
return c;
|
||||
}
|
||||
|
||||
internal static void AddChip(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 l = new Label(label + ":");
|
||||
l.style.opacity = 0.6f;
|
||||
l.style.fontSize = 11;
|
||||
l.style.marginRight = 3;
|
||||
chip.Add(l);
|
||||
|
||||
var v = new Label(value);
|
||||
v.style.fontSize = 11;
|
||||
v.style.unityFontStyleAndWeight = UnityEngine.FontStyle.Bold;
|
||||
chip.Add(v);
|
||||
parent.Add(chip);
|
||||
}
|
||||
|
||||
internal static VisualElement MakeActionBar()
|
||||
{
|
||||
var b = new VisualElement();
|
||||
b.style.flexDirection = FlexDirection.Row;
|
||||
b.style.paddingLeft = 12;
|
||||
b.style.paddingRight = 12;
|
||||
b.style.paddingTop = 6;
|
||||
b.style.paddingBottom = 6;
|
||||
b.style.flexWrap = Wrap.Wrap;
|
||||
return b;
|
||||
}
|
||||
|
||||
internal 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;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Button 扩展(模块内共用)─────────────────────────────────────────────
|
||||
internal static class ButtonExtensions
|
||||
{
|
||||
public static Button AlsoAddTo(this Button btn, VisualElement parent)
|
||||
{
|
||||
parent.Add(btn);
|
||||
return btn;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/_Game/Scripts/Editor/Modules/SkillModule.cs.meta
Normal file
11
Assets/_Game/Scripts/Editor/Modules/SkillModule.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f77603c5dde1584eade768456618cef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
184
Assets/_Game/Scripts/Editor/Modules/WeaponModule.cs
Normal file
184
Assets/_Game/Scripts/Editor/Modules/WeaponModule.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/_Game/Scripts/Editor/Modules/WeaponModule.cs.meta
Normal file
11
Assets/_Game/Scripts/Editor/Modules/WeaponModule.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b4131880a180b34d9f619b70813edb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user