using DanroJump.Gameplay; using UnityEditor; using UnityEngine; namespace DanroJump.Editor.Gameplay { /// /// Editor-окно для быстрой проверки текущего этапа сложности и прогресса генерации. /// public sealed class GameplayProgressionOverlayWindow : EditorWindow { /// /// Открывает overlay-окно прогрессии из меню Unity. /// [MenuItem("Window/Danro Jump/Gameplay Progression Overlay")] public static void Open() { var window = GetWindow("Progression"); window.minSize = new Vector2(320f, 180f); window.Show(); } /// /// Подписывается на editor update, чтобы overlay обновлялся без ручного Repaint. /// private void OnEnable() { EditorApplication.update += Repaint; } /// /// Снимает подписку на editor update при закрытии окна. /// private void OnDisable() { EditorApplication.update -= Repaint; } /// /// Рисует актуальные данные сцены без ручной привязки к конкретному объекту. /// private void OnGUI() { var progression = FindAnyObjectByType(); var spawner = FindAnyObjectByType(); GameplayProgressionOverlayGui.Draw(progression, spawner, true); } } /// /// Добавляет компактный preview прогрессии прямо в инспектор GameplayDifficultyProgression. /// [CustomEditor(typeof(GameplayDifficultyProgression))] public sealed class GameplayDifficultyProgressionEditor : UnityEditor.Editor { public override void OnInspectorGUI() { DrawDefaultInspector(); EditorGUILayout.Space(10f); var progression = (GameplayDifficultyProgression)target; var spawner = FindAnyObjectByType(); GameplayProgressionOverlayGui.Draw(progression, spawner, false); } } /// /// Общий IMGUI-рендерер для отдельного окна и встроенного блока в инспекторе. /// internal static class GameplayProgressionOverlayGui { /// /// Рисует состояние этапа игрока и этапа генерации платформ. /// public static void Draw(GameplayDifficultyProgression progression, PlatformSpawner spawner, bool showHeader) { if (showHeader) { EditorGUILayout.LabelField("Gameplay Progression", EditorStyles.boldLabel); EditorGUILayout.Space(4f); } if (progression == null) { EditorGUILayout.HelpBox("GameplayDifficultyProgression не найден в открытой сцене.", MessageType.Warning); return; } DrawStageBlock( "Этап игрока", progression.CurrentStageName, progression.CurrentProgress, GetPlayModeHint()); EditorGUILayout.Space(8f); if (spawner == null) { EditorGUILayout.HelpBox("PlatformSpawner не найден в открытой сцене.", MessageType.Info); return; } DrawStageBlock( "Этап генерации платформ", spawner.CurrentGenerationStage, spawner.CurrentGenerationStageProgress, $"Generation Y: {spawner.CurrentGenerationY:0.##} | Distribution: {spawner.CurrentPlatformDistribution:0.##}"); } /// /// Рисует одну карточку этапа с числовым прогрессом и progress bar. /// private static void DrawStageBlock(string title, string stageName, float progress, string subtitle) { EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.LabelField(title, EditorStyles.boldLabel); EditorGUILayout.LabelField("Текущий этап", string.IsNullOrWhiteSpace(stageName) ? "<нет этапа>" : stageName); EditorGUILayout.LabelField("Прогресс этапа", $"{Mathf.Clamp01(progress) * 100f:0}%"); var rect = GUILayoutUtility.GetRect(18f, 18f, "TextField"); EditorGUI.ProgressBar(rect, Mathf.Clamp01(progress), $"{Mathf.Clamp01(progress):0.00}"); if (!string.IsNullOrWhiteSpace(subtitle)) { EditorGUILayout.Space(3f); EditorGUILayout.LabelField(subtitle, EditorStyles.miniLabel); } EditorGUILayout.EndVertical(); } /// /// Возвращает подсказку о том, из какого режима редактора сейчас читаются данные. /// private static string GetPlayModeHint() { return EditorApplication.isPlaying ? "Play Mode: данные обновляются runtime-логикой" : "Edit Mode: данные рассчитаны по текущим ссылкам сцены"; } } }