using DanroJump.Gameplay; using UnityEditor; using UnityEngine; namespace DanroJump.Editor.Gameplay { public sealed class GameplayProgressionOverlayWindow : EditorWindow { [MenuItem("Window/Danro Jump/Gameplay Progression Overlay")] public static void Open() { var window = GetWindow("Progression"); window.minSize = new Vector2(320f, 180f); window.Show(); } private void OnEnable() { EditorApplication.update += Repaint; } private void OnDisable() { EditorApplication.update -= Repaint; } private void OnGUI() { var progression = FindFirstObjectByType(); var spawner = FindFirstObjectByType(); GameplayProgressionOverlayGui.Draw(progression, spawner, true); } } [CustomEditor(typeof(GameplayDifficultyProgression))] public sealed class GameplayDifficultyProgressionEditor : UnityEditor.Editor { public override void OnInspectorGUI() { DrawDefaultInspector(); EditorGUILayout.Space(10f); var progression = (GameplayDifficultyProgression)target; var spawner = FindFirstObjectByType(); GameplayProgressionOverlayGui.Draw(progression, spawner, false); } } 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.##}"); } 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: данные рассчитаны по текущим ссылкам сцены"; } } }