UI系统优化

This commit is contained in:
2026-05-25 11:54:37 +08:00
parent c7057db27d
commit 3c812cfb41
130 changed files with 4738 additions and 477 deletions

View File

@@ -0,0 +1,121 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using BaseGames.UI;
namespace BaseGames.Editor.UI
{
/// <summary>
/// UIManager 自定义 Inspector。
///
/// 功能:
/// 1. 绘制默认 Inspector原有字段布局不变
/// 2. 在面板注册表下方实时显示验证状态:
/// · 红色错误PanelId 重复注册
/// · 黄色警告GameObject 引用为 null
/// · 绿色信息:全部验证通过
/// 3. 提供一键测试按钮(仅 Play Mode 有效)
/// </summary>
[CustomEditor(typeof(UIManager))]
public class UIManagerEditor : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
EditorGUILayout.Space(6);
EditorGUILayout.LabelField("── 注册表验证 ──────────────────────", EditorStyles.boldLabel);
var panelsProp = serializedObject.FindProperty("_panels");
if (panelsProp == null || !panelsProp.isArray || panelsProp.arraySize == 0)
{
EditorGUILayout.HelpBox("面板注册表为空,请在 Inspector 中添加面板绑定。", MessageType.Warning);
}
else
{
var seenIds = new HashSet<int>();
bool hasError = false;
bool hasWarning = false;
for (int i = 0; i < panelsProp.arraySize; i++)
{
var elem = panelsProp.GetArrayElementAtIndex(i);
var idProp = elem.FindPropertyRelative("id");
var rootProp = elem.FindPropertyRelative("root");
string idName = idProp != null
? idProp.enumDisplayNames[idProp.enumValueIndex]
: $"[{i}]";
if (rootProp != null && rootProp.objectReferenceValue == null)
{
EditorGUILayout.HelpBox($"[{i}] PanelId.{idName} 的 GameObject 引用为 null", MessageType.Warning);
hasWarning = true;
}
if (idProp != null && !seenIds.Add(idProp.enumValueIndex))
{
EditorGUILayout.HelpBox($"[{i}] PanelId.{idName} 重复注册!同一 ID 只允许绑定一个 GameObject。", MessageType.Error);
hasError = true;
}
}
if (!hasError && !hasWarning)
EditorGUILayout.HelpBox($"注册表验证通过 ✓ 共 {panelsProp.arraySize} 个面板", MessageType.Info);
}
EditorGUILayout.Space(4);
EditorGUILayout.LabelField("── 运行期快速测试(需 Play Mode─────", EditorStyles.boldLabel);
using (new EditorGUI.DisabledScope(!Application.isPlaying))
{
var manager = (UIManager)target;
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("打开 Pause")) manager.OpenPanel(PanelId.Pause);
if (GUILayout.Button("打开 Map")) manager.OpenPanel(PanelId.Map);
if (GUILayout.Button("打开 Shop")) manager.OpenPanel(PanelId.Shop);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("打开 CharmPanel")) manager.OpenPanel(PanelId.CharmPanel);
if (GUILayout.Button("打开 Settings")) manager.OpenPanel(PanelId.Settings);
if (GUILayout.Button("关闭栈顶面板")) manager.CloseTopPanel();
EditorGUILayout.EndHorizontal();
// ── 面板栈实时可视化 ───────────────────────────────────────────
EditorGUILayout.Space(4);
EditorGUILayout.LabelField("── 面板栈(栊顶 = 第一行)───────────────────", EditorStyles.boldLabel);
var snapshot = manager.EditorGetPanelSnapshot();
if (snapshot == null || snapshot.Length == 0)
{
EditorGUILayout.HelpBox("面板栈为空", MessageType.None);
}
else
{
for (int i = 0; i < snapshot.Length; i++)
{
var go = snapshot[i];
string label = go != null ? go.name : "(null)";
if (i == 0)
{
// 栈顶面板加粗显示
var style = new GUIStyle(EditorStyles.label)
{
fontStyle = FontStyle.Bold,
};
EditorGUILayout.LabelField($"▶ [{i}] {label} (栈顶)", style);
}
else
{
EditorGUILayout.LabelField($" [{i}] {label}");
}
}
}
}
}
public override bool RequiresConstantRepaint() => Application.isPlaying;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 95f2af7feffeab44799a4127da2c7f8f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: