refactor(editor): reorganize Editor directory and unify menu hierarchy
File directory changes (mirror Scripts/ module structure): - AbilityTypeDrawer.cs → Equipment/ - CharacterWizardWindow.cs → Character/ - FormEditorWindow.cs → Player/ - GMToolWindow.cs → Tools/ - SOManagerWindow.cs → Tools/ - Map/MapRoomDataEditor.cs → World/Map/ - Navigation/ (root) → Enemies/Navigation/ - Achievements/ → Progression/ Menu hierarchy changes (BaseGames/ top-level): - Data/: +Character Wizard (from Tools/), +Boss Skill Sequence (from Tools/) - Addressables/: +Addressable Batch Tool, +Asset Reference Graph, +Validate Address Keys (from Tools/Verification/) - Scene/Setup/: +Boot Flow Wizard, +Scaffold *, +Auto-Open Persistent (from Tools/) - Scene/: +Camera Area Setup (from Camera/), +Bake All NavSurfaces (from Tools/) - Events/: +Event Bus Monitor, +Event Chain Viewer, +Create/Reimport Event Channels (from Tools/) - Tools/Validation/: +Validate All SOs, +Apply/Validate Script Order (from Tools/ flat) - Tools/Maintenance/: +Missing Scripts/*, +Physics2D Layer Matrix/* (from Tools/ flat) Result: BaseGames/Tools/ reduced from 16 flat items to 4 items + 2 submenus Docs: update AssetFolderSpec §12 editor tool table with new menu paths Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
112
Assets/_Game/Scripts/Editor/Progression/AchievementSOEditor.cs
Normal file
112
Assets/_Game/Scripts/Editor/Progression/AchievementSOEditor.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using BaseGames.Progression;
|
||||
|
||||
namespace BaseGames.Editor.Achievements
|
||||
{
|
||||
/// <summary>
|
||||
/// AchievementSO 自定义 Inspector(架构 16_SupportingModules §2.4)。
|
||||
/// 在 conditions 数组中内联展示各 AchievementCondition SO 的关键字段,
|
||||
/// 并在头部显示条件类型的中文名,提供 Ping 和删除按钮。
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(AchievementSO))]
|
||||
public class AchievementSOEditor : UnityEditor.Editor
|
||||
{
|
||||
private static readonly Dictionary<string, string> _conditionLabels = new()
|
||||
{
|
||||
{ "DefeatedBossCondition", "击败 Boss" },
|
||||
{ "DefeatedAllBossesCondition", "击败全部 Boss" },
|
||||
{ "EnteredRegionCondition", "到达区域" },
|
||||
{ "MapExplorationCondition", "地图探索 %" },
|
||||
{ "CollectedItemCondition", "收集物品" },
|
||||
{ "CollectedAllCharmsCondition", "集满全部 Charm" },
|
||||
{ "UnlockedAllAbilitiesCondition", "解锁全部能力" },
|
||||
{ "NoHealRunCondition", "无治疗通关" },
|
||||
{ "TimedBossKillCondition", "限时击败 Boss" },
|
||||
{ "ParryCountCondition", "弹反 N 次" },
|
||||
{ "NailClashCountCondition", "拼刀 N 次" },
|
||||
{ "EventTriggeredCondition", "监听事件" },
|
||||
};
|
||||
|
||||
private SerializedProperty _conditionsProp;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_conditionsProp = serializedObject.FindProperty("conditions");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
// 绘制除 conditions 之外的所有默认字段
|
||||
DrawPropertiesExcluding(serializedObject, "conditions");
|
||||
|
||||
EditorGUILayout.Space(8);
|
||||
EditorGUILayout.LabelField("解锁条件(AND 全部满足)", EditorStyles.boldLabel);
|
||||
|
||||
for (int i = 0; i < _conditionsProp.arraySize; i++)
|
||||
{
|
||||
var elemProp = _conditionsProp.GetArrayElementAtIndex(i);
|
||||
var condSO = elemProp.objectReferenceValue as AchievementCondition;
|
||||
|
||||
string typeName = condSO?.GetType().Name ?? "";
|
||||
string label = condSO != null && _conditionLabels.TryGetValue(typeName, out var n)
|
||||
? $"{n} [{condSO.name}]"
|
||||
: (condSO != null ? $"{typeName} [{condSO.name}]" : "(未指定条件 SO)");
|
||||
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
|
||||
// 标题行
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(label, EditorStyles.boldLabel);
|
||||
|
||||
if (condSO != null && GUILayout.Button("↗", GUILayout.Width(24)))
|
||||
EditorGUIUtility.PingObject(condSO);
|
||||
|
||||
var prevColor = GUI.color;
|
||||
GUI.color = Color.red * 0.9f;
|
||||
if (GUILayout.Button("✕", GUILayout.Width(24)))
|
||||
{
|
||||
GUI.color = prevColor;
|
||||
// 先将引用置空再删除,避免删除保留引用的 Unity 行为
|
||||
_conditionsProp.GetArrayElementAtIndex(i).objectReferenceValue = null;
|
||||
_conditionsProp.DeleteArrayElementAtIndex(i);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
break;
|
||||
}
|
||||
GUI.color = prevColor;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
// 内联展开 SO 字段(可编辑)
|
||||
if (condSO != null)
|
||||
{
|
||||
var innerSO = new SerializedObject(condSO);
|
||||
innerSO.Update();
|
||||
var prop = innerSO.GetIterator();
|
||||
prop.NextVisible(true); // 跳过 m_Script
|
||||
while (prop.NextVisible(false))
|
||||
EditorGUILayout.PropertyField(prop, true);
|
||||
if (innerSO.ApplyModifiedProperties())
|
||||
EditorUtility.SetDirty(condSO);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(elemProp, GUIContent.none);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.Space(2);
|
||||
}
|
||||
|
||||
// 添加按钮
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("+ 添加条件 SO 引用"))
|
||||
_conditionsProp.arraySize++;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95b58f8c5a3285c4abbf929f7bf36946
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user