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: данные рассчитаны по текущим ссылкам сцены";
}
}
}