#if UNITY_EDITOR using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace ShrinkTutorial.Editor { public class ShrinkTutorialEditorWindow : EditorWindow { private ShrinkTutorialDatabase _database; private Vector2 _tutorialListScroll; private Vector2 _detailScroll; private ShrinkTutorialData _selectedTutorial; private UnityEditor.Editor _selectedTutorialEditor; private List _issues = new(); [MenuItem("ShrinkSDK/引导/教程编辑器")] public static void ShowWindow() { var window = GetWindow("引导系统"); window.minSize = new Vector2(960f, 580f); window.Show(); } [MenuItem("ShrinkSDK/Tutorial/Editor")] public static void ShowWindowAlias() { ShowWindow(); } [MenuItem("ShrinkSDK/引导/重置教程进度")] public static void ResetProgress() { var settings = ShrinkTutorialSettings.Instance; var key = settings ? settings.playerPrefsStorageKey : "ShrinkTutorial.Progress"; new PlayerPrefsShrinkTutorialStorage(key).Reset(); Debug.Log("[ShrinkTutorial] 已重置教程进度。"); } [MenuItem("ShrinkSDK/Tutorial/Reset Progress")] public static void ResetProgressAlias() { ResetProgress(); } private void OnEnable() { TryAssignDefaultDatabase(); } private void OnGUI() { DrawToolbar(); EditorGUILayout.BeginHorizontal(); DrawTutorialList(); DrawDetailPanel(); EditorGUILayout.EndHorizontal(); DrawIssues(); } private void DrawToolbar() { EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); _database = (ShrinkTutorialDatabase)EditorGUILayout.ObjectField(_database, typeof(ShrinkTutorialDatabase), false, GUILayout.Width(320f)); if (GUILayout.Button("从设置读取", EditorStyles.toolbarButton, GUILayout.Width(90f))) TryAssignDefaultDatabase(); if (GUILayout.Button("验证数据库", EditorStyles.toolbarButton, GUILayout.Width(90f))) ValidateDatabase(); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); } private void DrawTutorialList() { EditorGUILayout.BeginVertical(GUILayout.Width(280f)); EditorGUILayout.LabelField("教程列表", EditorStyles.boldLabel); if (!_database) { EditorGUILayout.HelpBox("请先指定 ShrinkTutorialDatabase。", MessageType.Info); EditorGUILayout.EndVertical(); return; } _tutorialListScroll = EditorGUILayout.BeginScrollView(_tutorialListScroll); foreach (var tutorial in _database.Tutorials) { using (new EditorGUI.DisabledScope(!tutorial)) { var label = tutorial ? $"{tutorial.tutorialId} ({tutorial.steps.Count} 步)" : "<空引用>"; if (GUILayout.Toggle(_selectedTutorial == tutorial, label, "Button")) SelectTutorial(tutorial); } } EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical(); } private void DrawDetailPanel() { EditorGUILayout.BeginVertical(); if (!_selectedTutorial) { EditorGUILayout.HelpBox("左侧选择一个教程后,这里会显示完整配置。", MessageType.Info); EditorGUILayout.EndVertical(); return; } EditorGUILayout.LabelField(_selectedTutorial.tutorialId, EditorStyles.boldLabel); _detailScroll = EditorGUILayout.BeginScrollView(_detailScroll); if (_selectedTutorialEditor == null) _selectedTutorialEditor = UnityEditor.Editor.CreateEditor(_selectedTutorial); _selectedTutorialEditor.OnInspectorGUI(); EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical(); } private void DrawIssues() { if (_issues.Count == 0) return; EditorGUILayout.Space(); EditorGUILayout.LabelField("校验结果", EditorStyles.boldLabel); foreach (var issue in _issues) EditorGUILayout.HelpBox(issue, MessageType.Warning); } private void TryAssignDefaultDatabase() { var settings = ShrinkTutorialSettings.Instance; if (settings) _database = settings.database; if (!_database) { var guids = AssetDatabase.FindAssets("t:ShrinkTutorialDatabase"); if (guids.Length > 0) { var path = AssetDatabase.GUIDToAssetPath(guids[0]); _database = AssetDatabase.LoadAssetAtPath(path); } } } private void ValidateDatabase() { _issues.Clear(); if (!_database) { _issues.Add("未指定 ShrinkTutorialDatabase。"); return; } _issues.AddRange(_database.Validate()); if (_issues.Count == 0) _issues.Add("未发现配置问题。"); } private void SelectTutorial(ShrinkTutorialData tutorial) { if (_selectedTutorial == tutorial) return; _selectedTutorial = tutorial; DestroyImmediate(_selectedTutorialEditor); _selectedTutorialEditor = null; } } } #endif