Files
zeling_v2/Assets/Scripts/Editor/Achievements/AchievementSOEditor.cs
2026-05-12 15:34:08 +08:00

113 lines
4.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.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();
}
}
}