From 27c0d200c99310327be12954ddd056f056aebf7b Mon Sep 17 00:00:00 2001 From: Joywayer Date: Thu, 21 May 2026 07:59:01 +0800 Subject: [PATCH] Refactor and clean up game assets and editor modules - Deleted unused weapon and enemy stat assets to streamline project. - Updated player form assets to reference new default weapon IDs. - Enhanced DataHub editor UI for better usability, including improved tab management and detail views. - Removed icon references in various editor modules to simplify the interface. - Added new boss skill assets and corresponding metadata for future development. - Created new folders and metadata for organizing boss-related assets, skills, and stats. - Implemented a new skill asset with updated properties for better gameplay mechanics. --- .../Weapons/WPN_New.asset.meta => Boss.meta} | 6 +- .../Sequences.meta} | 6 +- .../Skills.meta} | 6 +- .../Skills/ABL_Boss_New.asset} | 2 +- .../Skills/ABL_Boss_New.asset.meta} | 2 +- .../_Game/Data/Combat/Weapons/WPN_New.asset | 103 ------- .../_Game/Data/Enemies/BasicEnemyStats.asset | 28 -- Assets/_Game/Data/Enemies/ENM_New_Stats.asset | 28 -- Assets/_Game/Data/Enemies/Stats.meta | 8 + .../Data/Player/Forms/PLY_Form_DiHun.asset | 2 +- .../Data/Player/Forms/PLY_Form_MingHun.asset | 2 +- .../Data/Player/Forms/PLY_Form_TianHun.asset | 2 +- Assets/_Game/Data/Skills.meta | 8 + .../{Progression => }/Skills/SKL_New.asset | 4 +- .../Skills/SKL_New.asset.meta | 2 +- Assets/_Game/Data/Weapons.meta | 8 + .../_Game/Scripts/Editor/Hub/DataHubWindow.cs | 32 ++- .../Scripts/Editor/Modules/BossSkillModule.cs | 2 +- .../Scripts/Editor/Modules/EnemyModule.cs | 2 +- .../Scripts/Editor/Modules/FormModule.cs | 263 +++++++++++++----- .../Scripts/Editor/Modules/SkillModule.cs | 2 +- .../Scripts/Editor/Modules/WeaponModule.cs | 2 +- .../_Game/Scripts/Editor/Shared/SoListPane.cs | 52 ++-- 23 files changed, 282 insertions(+), 290 deletions(-) rename Assets/_Game/Data/{Combat/Weapons/WPN_New.asset.meta => Boss.meta} (52%) rename Assets/_Game/Data/{Enemies/SKL_Boss_New.asset.meta => Boss/Sequences.meta} (52%) rename Assets/_Game/Data/{Enemies/BasicEnemyStats.asset.meta => Boss/Skills.meta} (52%) rename Assets/_Game/Data/{Enemies/SKL_Boss_New.asset => Boss/Skills/ABL_Boss_New.asset} (97%) rename Assets/_Game/Data/{Enemies/ENM_New_Stats.asset.meta => Boss/Skills/ABL_Boss_New.asset.meta} (79%) delete mode 100644 Assets/_Game/Data/Combat/Weapons/WPN_New.asset delete mode 100644 Assets/_Game/Data/Enemies/BasicEnemyStats.asset delete mode 100644 Assets/_Game/Data/Enemies/ENM_New_Stats.asset create mode 100644 Assets/_Game/Data/Enemies/Stats.meta create mode 100644 Assets/_Game/Data/Skills.meta rename Assets/_Game/Data/{Progression => }/Skills/SKL_New.asset (96%) rename Assets/_Game/Data/{Progression => }/Skills/SKL_New.asset.meta (79%) create mode 100644 Assets/_Game/Data/Weapons.meta diff --git a/Assets/_Game/Data/Combat/Weapons/WPN_New.asset.meta b/Assets/_Game/Data/Boss.meta similarity index 52% rename from Assets/_Game/Data/Combat/Weapons/WPN_New.asset.meta rename to Assets/_Game/Data/Boss.meta index d555971..9cdb5a3 100644 --- a/Assets/_Game/Data/Combat/Weapons/WPN_New.asset.meta +++ b/Assets/_Game/Data/Boss.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: ce7bc9bad6f58ec42baff08f5353340e -NativeFormatImporter: +guid: 1e65813de43bbcf47a845b96ec50aaa8 +folderAsset: yes +DefaultImporter: externalObjects: {} - mainObjectFileID: 11400000 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/_Game/Data/Enemies/SKL_Boss_New.asset.meta b/Assets/_Game/Data/Boss/Sequences.meta similarity index 52% rename from Assets/_Game/Data/Enemies/SKL_Boss_New.asset.meta rename to Assets/_Game/Data/Boss/Sequences.meta index 374a497..edb6a63 100644 --- a/Assets/_Game/Data/Enemies/SKL_Boss_New.asset.meta +++ b/Assets/_Game/Data/Boss/Sequences.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: a5d737a5b9641124aafb375d8684e06a -NativeFormatImporter: +guid: d142c2bb2dcf07449b612bbce4a5e7c5 +folderAsset: yes +DefaultImporter: externalObjects: {} - mainObjectFileID: 11400000 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/_Game/Data/Enemies/BasicEnemyStats.asset.meta b/Assets/_Game/Data/Boss/Skills.meta similarity index 52% rename from Assets/_Game/Data/Enemies/BasicEnemyStats.asset.meta rename to Assets/_Game/Data/Boss/Skills.meta index bda8184..90f481b 100644 --- a/Assets/_Game/Data/Enemies/BasicEnemyStats.asset.meta +++ b/Assets/_Game/Data/Boss/Skills.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: fc82960f3abbb7e4fa59e1471a1a3d6d -NativeFormatImporter: +guid: fe343668122cd07449a451983cce1dfe +folderAsset: yes +DefaultImporter: externalObjects: {} - mainObjectFileID: 11400000 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/_Game/Data/Enemies/SKL_Boss_New.asset b/Assets/_Game/Data/Boss/Skills/ABL_Boss_New.asset similarity index 97% rename from Assets/_Game/Data/Enemies/SKL_Boss_New.asset rename to Assets/_Game/Data/Boss/Skills/ABL_Boss_New.asset index 68fc23c..e387934 100644 --- a/Assets/_Game/Data/Enemies/SKL_Boss_New.asset +++ b/Assets/_Game/Data/Boss/Skills/ABL_Boss_New.asset @@ -10,7 +10,7 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: de92221c7c3fb4a42a7cd122a8f97632, type: 3} - m_Name: SKL_Boss_New + m_Name: ABL_Boss_New m_EditorClassIdentifier: skillId: displayName: diff --git a/Assets/_Game/Data/Enemies/ENM_New_Stats.asset.meta b/Assets/_Game/Data/Boss/Skills/ABL_Boss_New.asset.meta similarity index 79% rename from Assets/_Game/Data/Enemies/ENM_New_Stats.asset.meta rename to Assets/_Game/Data/Boss/Skills/ABL_Boss_New.asset.meta index d0f560c..ed3ee9d 100644 --- a/Assets/_Game/Data/Enemies/ENM_New_Stats.asset.meta +++ b/Assets/_Game/Data/Boss/Skills/ABL_Boss_New.asset.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e0cf93e053ead744fa1876771ba0d081 +guid: a21fed7fb6abbd6458ee5f69cf8cf603 NativeFormatImporter: externalObjects: {} mainObjectFileID: 11400000 diff --git a/Assets/_Game/Data/Combat/Weapons/WPN_New.asset b/Assets/_Game/Data/Combat/Weapons/WPN_New.asset deleted file mode 100644 index 03b8473..0000000 --- a/Assets/_Game/Data/Combat/Weapons/WPN_New.asset +++ /dev/null @@ -1,103 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!114 &11400000 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d2443d04d1c179d4d8a4f36e7ca7156e, type: 3} - m_Name: WPN_New - m_EditorClassIdentifier: - weaponId: - displayName: - icon: {fileID: 0} - weaponType: 0 - groundComboSteps: - - clip: - _FadeDuration: 0.25 - _Speed: 1 - _Events: - _NormalizedTimes: [] - _Callbacks: [] - _Names: [] - _Clip: {fileID: 0} - _NormalizedStartTime: NaN - damageSource: {fileID: 0} - hitBoxEnter: 0.3 - hitBoxExit: 0.6 - comboInputOpen: 0.3 - comboInputClose: 0 - cancelWindowOpen: 0.5 - recoveryTime: 0.05 - comboTimeout: 0.25 - hitBoxId: - airComboSteps: - - clip: - _FadeDuration: 0.25 - _Speed: 1 - _Events: - _NormalizedTimes: [] - _Callbacks: [] - _Names: [] - _Clip: {fileID: 0} - _NormalizedStartTime: NaN - damageSource: {fileID: 0} - hitBoxEnter: 0.1 - hitBoxExit: 0.8 - comboInputOpen: 0 - comboInputClose: 0 - cancelWindowOpen: 0 - recoveryTime: 0.05 - comboTimeout: 0 - hitBoxId: - upStep: - clip: - _FadeDuration: 0.25 - _Speed: 1 - _Events: - _NormalizedTimes: [] - _Callbacks: [] - _Names: [] - _Clip: {fileID: 0} - _NormalizedStartTime: NaN - damageSource: {fileID: 0} - hitBoxEnter: 0.2 - hitBoxExit: 0.7 - comboInputOpen: 0 - comboInputClose: 0 - cancelWindowOpen: 0 - recoveryTime: 0.05 - comboTimeout: 0 - hitBoxId: - downStep: - clip: - _FadeDuration: 0.25 - _Speed: 1 - _Events: - _NormalizedTimes: [] - _Callbacks: [] - _Names: [] - _Clip: {fileID: 0} - _NormalizedStartTime: NaN - damageSource: {fileID: 0} - hitBoxEnter: 0.1 - hitBoxExit: 0.9 - comboInputOpen: 0 - comboInputClose: 0 - cancelWindowOpen: 0 - recoveryTime: 0.05 - comboTimeout: 0 - hitBoxId: - hitBoxPrefab: {fileID: 0} - vfxConfig: - onEquipPresetId: - weaponTrailPrefab: {fileID: 0} - trailColor: {r: 1, g: 1, b: 1, a: 1} - soulPowerGain: 10 - references: - version: 2 - RefIds: [] diff --git a/Assets/_Game/Data/Enemies/BasicEnemyStats.asset b/Assets/_Game/Data/Enemies/BasicEnemyStats.asset deleted file mode 100644 index 9d6e986..0000000 --- a/Assets/_Game/Data/Enemies/BasicEnemyStats.asset +++ /dev/null @@ -1,28 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!114 &11400000 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ed4391dfa14c0304c8932f1ef9f8ce63, type: 3} - m_Name: BasicEnemyStats - m_EditorClassIdentifier: - MaxHP: 50 - Defense: 0 - WalkSpeed: 2 - RunSpeed: 4 - AttackDamage: 10 - AttackRange: 1.5 - AttackCooldown: 1 - DetectRange: 6 - KnockbackForce: 5 - HitStunDuration: 0.3 - EyeOffset: {x: 0, y: 0} - LOSBlockingMask: - serializedVersion: 2 - m_Bits: 0 diff --git a/Assets/_Game/Data/Enemies/ENM_New_Stats.asset b/Assets/_Game/Data/Enemies/ENM_New_Stats.asset deleted file mode 100644 index 6da7a55..0000000 --- a/Assets/_Game/Data/Enemies/ENM_New_Stats.asset +++ /dev/null @@ -1,28 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!114 &11400000 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ed4391dfa14c0304c8932f1ef9f8ce63, type: 3} - m_Name: ENM_New_Stats - m_EditorClassIdentifier: - MaxHP: 50 - Defense: 0 - WalkSpeed: 2 - RunSpeed: 4 - AttackDamage: 10 - AttackRange: 1.5 - AttackCooldown: 1 - DetectRange: 6 - KnockbackForce: 5 - HitStunDuration: 0.3 - EyeOffset: {x: 0, y: 0.8} - LOSBlockingMask: - serializedVersion: 2 - m_Bits: 1 diff --git a/Assets/_Game/Data/Enemies/Stats.meta b/Assets/_Game/Data/Enemies/Stats.meta new file mode 100644 index 0000000..5b62568 --- /dev/null +++ b/Assets/_Game/Data/Enemies/Stats.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 54d9d8593eb84d64c945a4af01b4e284 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Data/Player/Forms/PLY_Form_DiHun.asset b/Assets/_Game/Data/Player/Forms/PLY_Form_DiHun.asset index 513c251..de3df9c 100644 --- a/Assets/_Game/Data/Player/Forms/PLY_Form_DiHun.asset +++ b/Assets/_Game/Data/Player/Forms/PLY_Form_DiHun.asset @@ -15,5 +15,5 @@ MonoBehaviour: formId: DiHun displayName: "\u5730\u9B42" formType: 1 - defaultWeapon: {fileID: 0} + defaultWeapon: {fileID: 11400000, guid: bde7d85bdf2d3e54da22d07b1f8d2901, type: 2} formAccentColor: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/_Game/Data/Player/Forms/PLY_Form_MingHun.asset b/Assets/_Game/Data/Player/Forms/PLY_Form_MingHun.asset index 85dd232..8c4877e 100644 --- a/Assets/_Game/Data/Player/Forms/PLY_Form_MingHun.asset +++ b/Assets/_Game/Data/Player/Forms/PLY_Form_MingHun.asset @@ -15,5 +15,5 @@ MonoBehaviour: formId: MingHun displayName: "\u547D\u9B42" formType: 2 - defaultWeapon: {fileID: 0} + defaultWeapon: {fileID: 11400000, guid: fbe1ff6f23c995541a5833b51c52dc01, type: 2} formAccentColor: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/_Game/Data/Player/Forms/PLY_Form_TianHun.asset b/Assets/_Game/Data/Player/Forms/PLY_Form_TianHun.asset index 1b7862b..bd07c54 100644 --- a/Assets/_Game/Data/Player/Forms/PLY_Form_TianHun.asset +++ b/Assets/_Game/Data/Player/Forms/PLY_Form_TianHun.asset @@ -15,5 +15,5 @@ MonoBehaviour: formId: TianHun displayName: "\u5929\u9B42" formType: 0 - defaultWeapon: {fileID: 0} + defaultWeapon: {fileID: 11400000, guid: 533d4711e21d8584597a5d4569fe2eb0, type: 2} formAccentColor: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/_Game/Data/Skills.meta b/Assets/_Game/Data/Skills.meta new file mode 100644 index 0000000..4750e80 --- /dev/null +++ b/Assets/_Game/Data/Skills.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cef22fc8fa1b2ba43b93debfa27b561d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Data/Progression/Skills/SKL_New.asset b/Assets/_Game/Data/Skills/SKL_New.asset similarity index 96% rename from Assets/_Game/Data/Progression/Skills/SKL_New.asset rename to Assets/_Game/Data/Skills/SKL_New.asset index 61c132b..f5e2aa3 100644 --- a/Assets/_Game/Data/Progression/Skills/SKL_New.asset +++ b/Assets/_Game/Data/Skills/SKL_New.asset @@ -16,7 +16,7 @@ MonoBehaviour: displayNameKey: descriptionKey: icon: {fileID: 0} - resourceType: 1 + resourceType: 0 baseCost: 0 cooldown: 0 castAnimation: @@ -29,7 +29,7 @@ MonoBehaviour: _Clip: {fileID: 0} _NormalizedStartTime: NaN castLockDuration: 0 - effectType: 1 + effectType: 0 damageSource: {fileID: 0} projectileConfig: {fileID: 0} isHoming: 0 diff --git a/Assets/_Game/Data/Progression/Skills/SKL_New.asset.meta b/Assets/_Game/Data/Skills/SKL_New.asset.meta similarity index 79% rename from Assets/_Game/Data/Progression/Skills/SKL_New.asset.meta rename to Assets/_Game/Data/Skills/SKL_New.asset.meta index 6ead2d9..00dc87e 100644 --- a/Assets/_Game/Data/Progression/Skills/SKL_New.asset.meta +++ b/Assets/_Game/Data/Skills/SKL_New.asset.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d00e0d6104f281345b8978d3a72eed13 +guid: a3b44b259b9480c44b82d01b8682dac0 NativeFormatImporter: externalObjects: {} mainObjectFileID: 11400000 diff --git a/Assets/_Game/Data/Weapons.meta b/Assets/_Game/Data/Weapons.meta new file mode 100644 index 0000000..05be79b --- /dev/null +++ b/Assets/_Game/Data/Weapons.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b7d50bcddabe6ed42b2ae83cef9e3e9c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Game/Scripts/Editor/Hub/DataHubWindow.cs b/Assets/_Game/Scripts/Editor/Hub/DataHubWindow.cs index e3188a4..4d789b0 100644 --- a/Assets/_Game/Scripts/Editor/Hub/DataHubWindow.cs +++ b/Assets/_Game/Scripts/Editor/Hub/DataHubWindow.cs @@ -100,15 +100,19 @@ namespace BaseGames.Editor split.style.flexGrow = 1; root.Add(split); - // 列表区容器 + // 列表区容器(TwoPaneSplitView 管理宽度,不需要 flexGrow) _listWrapper = new VisualElement(); - _listWrapper.style.flexGrow = 1; + _listWrapper.style.flexGrow = 1; + _listWrapper.style.overflow = Overflow.Hidden; split.Add(_listWrapper); - // 详情区容器 - _detailWrapper = new VisualElement(); - _detailWrapper.style.flexGrow = 1; - split.Add(_detailWrapper); + // 详情区容器(ScrollView 支持超长内容滚动) + var detailScroll = new ScrollView(ScrollViewMode.Vertical); + detailScroll.style.flexGrow = 1; + detailScroll.contentContainer.style.flexGrow = 1; + detailScroll.contentContainer.style.flexDirection = FlexDirection.Column; + split.Add(detailScroll); + _detailWrapper = detailScroll.contentContainer; } private VisualElement BuildNavSidebar() @@ -163,14 +167,18 @@ namespace BaseGames.Editor btn.style.backgroundColor = new StyleColor(Color.clear); btn.style.marginBottom = 2; - // 图标 + // 图标(容错:图标名无效时跳过,不报错) if (!string.IsNullOrEmpty(module.IconName)) { - var icon = new Image { image = EditorGUIUtility.IconContent(module.IconName).image }; - icon.style.width = 16; - icon.style.height = 16; - icon.style.marginRight = 6; - btn.Add(icon); + var content = EditorGUIUtility.IconContent(module.IconName); + if (content?.image != null) + { + var icon = new Image { image = content.image }; + icon.style.width = 16; + icon.style.height = 16; + icon.style.marginRight = 6; + btn.Add(icon); + } } var label = new Label(module.DisplayName); diff --git a/Assets/_Game/Scripts/Editor/Modules/BossSkillModule.cs b/Assets/_Game/Scripts/Editor/Modules/BossSkillModule.cs index 5fc37bf..f16ca26 100644 --- a/Assets/_Game/Scripts/Editor/Modules/BossSkillModule.cs +++ b/Assets/_Game/Scripts/Editor/Modules/BossSkillModule.cs @@ -17,7 +17,7 @@ namespace BaseGames.Editor.Modules public string ModuleId => "boss"; public string DisplayName => "Boss技能"; - public string IconName => "d_SkinnedMeshRenderer Icon"; + public string IconName => null; private int _activeTab = 0; diff --git a/Assets/_Game/Scripts/Editor/Modules/EnemyModule.cs b/Assets/_Game/Scripts/Editor/Modules/EnemyModule.cs index dffdc65..ab8c4db 100644 --- a/Assets/_Game/Scripts/Editor/Modules/EnemyModule.cs +++ b/Assets/_Game/Scripts/Editor/Modules/EnemyModule.cs @@ -17,7 +17,7 @@ namespace BaseGames.Editor.Modules public string ModuleId => "enemy"; public string DisplayName => "敌人"; - public string IconName => "d_Avatar Icon"; + public string IconName => null; private int _activeTab = 0; // 0=Stats, 1=Loot diff --git a/Assets/_Game/Scripts/Editor/Modules/FormModule.cs b/Assets/_Game/Scripts/Editor/Modules/FormModule.cs index 3ea7408..80e99a1 100644 --- a/Assets/_Game/Scripts/Editor/Modules/FormModule.cs +++ b/Assets/_Game/Scripts/Editor/Modules/FormModule.cs @@ -8,7 +8,7 @@ using BaseGames.Player; namespace BaseGames.Editor.Modules { /// - /// DataHub 形态模块 —— 管理 FormConfigSO(含三列 FormSO 预览)和 FormSO 资产。 + /// DataHub 形态模块 —— Tab 切换管理 FormConfigSO 和 FormSO 资产。 /// public class FormModule : IDataModule { @@ -17,11 +17,17 @@ namespace BaseGames.Editor.Modules public string ModuleId => "form"; public string DisplayName => "形态"; - public string IconName => "d_AvatarPivot"; + public string IconName => null; - private SoListPane _listPane; - private DetailHeader _header; - private FormConfigSO _selected; + private int _activeTab = 0; // 0=FormConfig, 1=FormSO + + private SoListPane _configPane; + private SoListPane _formPane; + private Action _onSelected; + + private DetailHeader _header; + private FormConfigSO _selectedConfig; + private FormSO _selectedForm; private static readonly (FormType type, string label, Color accent)[] FormDefs = { @@ -32,59 +38,137 @@ namespace BaseGames.Editor.Modules public void Initialize() { - _listPane = new SoListPane(ConfigFolder, "PLY_FormConfig_"); + _configPane = new SoListPane(ConfigFolder, "PLY_FormConfig_"); + _configPane.SelectionChanged = s => { _selectedConfig = s; _onSelected?.Invoke(s); }; + + _formPane = new SoListPane(FormFolder, "PLY_Form_", + f => f.formType.ToString()); + _formPane.SelectionChanged = s => { _selectedForm = s; _onSelected?.Invoke(s); }; } public void BuildListPane(VisualElement container, Action onSelected) { - _listPane.SelectionChanged = sel => - { - _selected = sel; - onSelected?.Invoke(sel); - }; - container.Add(_listPane); - _listPane.Refresh(); + _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 btnConfig = BuildTabBtn("配置 (Config)", 0, tabBar); + var btnForm = BuildTabBtn("形态 (Form)", 1, tabBar); + + var listArea = new VisualElement(); + listArea.style.flexGrow = 1; + container.Add(listArea); + + ShowTab(0, listArea, new[] { btnConfig, btnForm }); + btnConfig.clicked += () => ShowTab(0, listArea, new[] { btnConfig, btnForm }); + btnForm.clicked += () => ShowTab(1, listArea, new[] { btnConfig, btnForm }); + + _configPane.Refresh(); + _formPane.Refresh(); } public void BuildDetailPane(VisualElement container, UnityEngine.Object selected) { - _selected = selected as FormConfigSO; - _header = new DetailHeader(); - _header.SetAsset(_selected); - _header.RenameRequested += OnRenameRequested; + _header.SetAsset(selected); + _header.RenameRequested += name => OnRenameRequested(selected, name); container.Add(_header); - if (_selected == null) return; + 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); + if (selected is FormConfigSO config) + { + container.Add(BuildConfigActionBar(config)); + container.Add(SkillModule.MakeDivider()); + container.Add(BuildFormGrid(config)); + container.Add(SkillModule.MakeDivider()); + var insp = new InspectorElement(config); + insp.style.flexGrow = 1; + container.Add(insp); + } + else if (selected is FormSO form) + { + container.Add(BuildFormCard(form)); + container.Add(BuildFormActionBar(form)); + container.Add(SkillModule.MakeDivider()); + var insp = new InspectorElement(form); + insp.style.flexGrow = 1; + container.Add(insp); + } } - public void OnActivated() => _listPane?.Refresh(); - - // ── 内部 ───────────────────────────────────────────────────────────── - - private void OnRenameRequested(string newName) + public void OnActivated() { - if (_selected == null) return; - var (ok, err) = AssetOperations.Rename(_selected, newName); - if (!ok) EditorUtility.DisplayDialog("重命名失败", err, "确定"); - else { _header.SetAsset(_selected); _listPane.Invalidate(); } + _configPane?.Refresh(); + _formPane?.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) { _configPane.style.flexGrow = 1; area.Add(_configPane); } + else { _formPane.style.flexGrow = 1; area.Add(_formPane); } + } + + // ── 重命名 ──────────────────────────────────────────────────────────── + + 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) _configPane.Invalidate(); + else _formPane.Invalidate(); + } + } + + // ── FormConfigSO 详情 ───────────────────────────────────────────────── + private VisualElement BuildFormGrid(FormConfigSO config) { var grid = new VisualElement(); @@ -108,17 +192,17 @@ namespace BaseGames.Editor.Modules 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.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; @@ -133,8 +217,8 @@ namespace BaseGames.Editor.Modules titleRow.style.marginBottom = 6; var dot = new VisualElement(); - dot.style.width = 10; - dot.style.height = 10; + dot.style.width = 10; + dot.style.height = 10; dot.style.borderTopLeftRadius = 5; dot.style.borderTopRightRadius = 5; dot.style.borderBottomLeftRadius = 5; @@ -149,10 +233,7 @@ namespace BaseGames.Editor.Modules 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); - }); + SetFormByType(config, ft, e.newValue as FormSO)); col.Add(formField); // 武器只读预览 @@ -179,31 +260,59 @@ namespace BaseGames.Editor.Modules EditorUtility.SetDirty(config); } - private VisualElement BuildActionBar(FormConfigSO config) + private VisualElement BuildConfigActionBar(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; + new Button(() => { var c = AssetOperations.Clone(config, ConfigFolder); if (c != null) _configPane.Refresh(c); }) + { text = "克隆..." }.AlsoAddTo(bar); + var del = new Button(() => { if (AssetOperations.Delete(config)) _configPane.Refresh(null); }) { text = "删除" }; + ApplyDeleteStyle(del); del.AlsoAddTo(bar); return bar; } + + // ── FormSO 详情 ─────────────────────────────────────────────────────── + + private static VisualElement BuildFormCard(FormSO f) + { + var card = SkillModule.MakeCard(); + SkillModule.AddChip(card, "类型", f.formType.ToString()); + SkillModule.AddChip(card, "ID", string.IsNullOrEmpty(f.formId) ? "-" : f.formId); + SkillModule.AddChip(card, "显示名", string.IsNullOrEmpty(f.displayName) ? "-" : f.displayName); + if (f.defaultWeapon != null) + SkillModule.AddChip(card, "默认武器", f.defaultWeapon.name); + return card; + } + + private VisualElement BuildFormActionBar(FormSO form) + { + var bar = SkillModule.MakeActionBar(); + new Button(() => { EditorGUIUtility.PingObject(form); Selection.activeObject = form; }) + { text = "定位" }.AlsoAddTo(bar); + new Button(() => { var c = AssetOperations.Clone(form, FormFolder); if (c != null) _formPane.Refresh(c); }) + { text = "克隆..." }.AlsoAddTo(bar); + var del = new Button(() => { if (AssetOperations.Delete(form)) _formPane.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; + } } } diff --git a/Assets/_Game/Scripts/Editor/Modules/SkillModule.cs b/Assets/_Game/Scripts/Editor/Modules/SkillModule.cs index 3e89876..ac8643d 100644 --- a/Assets/_Game/Scripts/Editor/Modules/SkillModule.cs +++ b/Assets/_Game/Scripts/Editor/Modules/SkillModule.cs @@ -17,7 +17,7 @@ namespace BaseGames.Editor.Modules public string ModuleId => "skill"; public string DisplayName => "技能"; - public string IconName => "d_Lighting Icon"; + public string IconName => null; private SoListPane _listPane; private DetailHeader _header; diff --git a/Assets/_Game/Scripts/Editor/Modules/WeaponModule.cs b/Assets/_Game/Scripts/Editor/Modules/WeaponModule.cs index d9b9a2e..4a27144 100644 --- a/Assets/_Game/Scripts/Editor/Modules/WeaponModule.cs +++ b/Assets/_Game/Scripts/Editor/Modules/WeaponModule.cs @@ -17,7 +17,7 @@ namespace BaseGames.Editor.Modules public string ModuleId => "weapon"; public string DisplayName => "武器"; - public string IconName => "d_Sword Icon"; + public string IconName => null; private SoListPane _listPane; private DetailHeader _header; diff --git a/Assets/_Game/Scripts/Editor/Shared/SoListPane.cs b/Assets/_Game/Scripts/Editor/Shared/SoListPane.cs index 0483d74..b21b97f 100644 --- a/Assets/_Game/Scripts/Editor/Shared/SoListPane.cs +++ b/Assets/_Game/Scripts/Editor/Shared/SoListPane.cs @@ -53,29 +53,36 @@ namespace BaseGames.Editor private void BuildUI() { - // Toolbar - var toolbar = new VisualElement(); - toolbar.style.flexDirection = FlexDirection.Row; - toolbar.style.alignItems = Align.Center; - toolbar.style.paddingLeft = 6; - toolbar.style.paddingRight = 6; - toolbar.style.paddingTop = 5; - toolbar.style.paddingBottom = 5; - toolbar.style.borderBottomWidth = 1; - toolbar.style.borderBottomColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f, 0.3f)); - Add(toolbar); + // 搜索栏 + var searchRow = new VisualElement(); + searchRow.style.flexDirection = FlexDirection.Row; + searchRow.style.alignItems = Align.Center; + searchRow.style.paddingLeft = 6; + searchRow.style.paddingRight = 6; + searchRow.style.paddingTop = 5; + searchRow.style.paddingBottom = 4; + Add(searchRow); var searchField = new TextField(); - searchField.style.flexGrow = 1; - searchField.style.marginRight = 4; + searchField.style.flexGrow = 1; + searchField.style.minWidth = 0; searchField.RegisterValueChangedCallback(e => { _search = e.newValue; ApplyFilter(); }); - toolbar.Add(searchField); + searchRow.Add(searchField); + // 新建按钮(独占一行,宽度填满) var btnNew = new Button(OnCreateClicked) { text = "+ 新建" }; - btnNew.style.height = 20; - btnNew.style.paddingLeft = 8; - btnNew.style.paddingRight = 8; - toolbar.Add(btnNew); + btnNew.style.marginLeft = 6; + btnNew.style.marginRight = 6; + btnNew.style.marginBottom = 4; + btnNew.style.height = 22; + Add(btnNew); + + // 分隔线 + var sep = new VisualElement(); + sep.style.height = 1; + sep.style.backgroundColor = new StyleColor(new Color(0.5f, 0.5f, 0.5f, 0.25f)); + sep.style.marginBottom = 2; + Add(sep); // ListView _listView = new ListView(_filtered, 24, MakeItem, BindItem); @@ -92,9 +99,9 @@ namespace BaseGames.Editor // Count footer _countLabel = new Label(); - _countLabel.style.fontSize = 10; - _countLabel.style.opacity = 0.55f; - _countLabel.style.paddingLeft = 6; + _countLabel.style.fontSize = 10; + _countLabel.style.opacity = 0.55f; + _countLabel.style.paddingLeft = 6; _countLabel.style.paddingBottom = 3; _countLabel.style.paddingTop = 2; Add(_countLabel); @@ -220,6 +227,9 @@ namespace BaseGames.Editor { _listView.SetSelection(i); _listView.ScrollToItem(i); + // SetSelection 在 RefreshItems 同帧内不保证触发 onSelectionChange, + // 显式调用以确保详情区始终同步。 + SelectionChanged?.Invoke(_filtered[i]); return; } }