using UnityEngine; using RR.Common.Managers; using RR.Common.Prizes; using RR.Game2D.Core.Managers; namespace RR.Game2D.Behaviour { /// /// Компонент финиша уровня с возможностью выдачи приза. /// Устанавливается на объект с триггером и тегом "Finish". /// [RequireComponent(typeof(Collider2D))] public class LevelFinish : MonoBehaviour { [Header("Настройки приза")] [Tooltip("Включить выдачу приза при завершении уровня")] [SerializeField] private bool enablePrizeOnFinish = true; [Tooltip("Задержка перед выдачей приза (в секундах)")] [SerializeField] private float prizeDelay = 0.5f; [Header("Отладка")] [SerializeField] private bool debugMode; private bool _prizeGiven; private bool _waitingForPrize; private void OnTriggerEnter2D(Collider2D collision) { // Проверяем, что это игрок if (!collision.CompareTag("Player")) return; if (GameManager.Instance != null && GameManager.Instance.IsCurrentLevelFinal()) { GameManager.Instance.SetPendingWinGameTime(GameManager.Instance.GetCurrentGameTime()); } if (enablePrizeOnFinish && !_prizeGiven && HasPrizeForCurrentLevel()) { // Есть приз — выдаём и ждём результата, потом переходим TryGivePrize(); } else { // Приза нет или он отключён — переходим сразу GameManager.Instance.NextLevel(); } } /// /// Проверяет, назначен ли приз для текущего уровня. /// private bool HasPrizeForCurrentLevel() { var psm = PrizeSystemManager.Instance; if (psm == null || psm.Database == null) return false; string level = $"{GameManager.Instance.World}-{GameManager.Instance.Stage}"; LevelPrizeConfig config = psm.Database.GetConfig(level); return config.type != PrizeType.None; } /// /// Пытается выдать приз игроку, если выполнены все условия. /// private void TryGivePrize() { // Проверка, что приз еще не был выдан if (_prizeGiven) { if (debugMode) Debug.Log("[LevelFinish] Приз уже был выдан на этом финише."); return; } // Проверка, включена ли выдача призов в этом компоненте if (!enablePrizeOnFinish) { if (debugMode) Debug.Log("[LevelFinish] Выдача призов отключена в компоненте."); return; } _prizeGiven = true; _waitingForPrize = true; // Подписываемся на результат выдачи приза var psm = PrizeSystemManager.Instance; if (psm != null) psm.OnAnyPrizeResult += OnPrizeFinished; if (prizeDelay > 0) { Invoke(nameof(GivePrize), prizeDelay); } else { GivePrize(); } } /// /// Вызывается после завершения выдачи приза (успешно или нет). /// private void OnPrizeFinished(PrizeType type, bool success) { if (!_waitingForPrize) return; _waitingForPrize = false; var psm = PrizeSystemManager.Instance; if (psm != null) psm.OnAnyPrizeResult -= OnPrizeFinished; if (debugMode) Debug.Log($"[LevelFinish] Приз «{type}» завершён (успех: {success}). Переход на следующий уровень."); GameManager.Instance.NextLevel(); } /// /// Выдает приз через PrizeSystemManager — тип приза берётся из JSON-базы для текущего уровня. /// private void GivePrize() { if (debugMode) Debug.Log("[LevelFinish] Выдаю приз игроку!"); if (PrizeSystemManager.Instance != null) PrizeSystemManager.Instance.GivePrizeForCurrentLevel(); else { if (debugMode) Debug.LogWarning("[LevelFinish] PrizeSystemManager не найден."); // Если менеджер не найден — переходим сразу _waitingForPrize = false; GameManager.Instance.NextLevel(); } } /// /// Сбрасывает состояние выдачи приза (для повторного использования). /// public void ResetPrize() { _prizeGiven = false; _waitingForPrize = false; } private void OnDestroy() { if (_waitingForPrize) { var psm = PrizeSystemManager.Instance; if (psm != null) psm.OnAnyPrizeResult -= OnPrizeFinished; } } #if UNITY_EDITOR private void OnDrawGizmos() { // Визуализация зоны финиша в редакторе Collider2D col = GetComponent(); if (col != null) { Gizmos.color = enablePrizeOnFinish ? Color.green : Color.yellow; Gizmos.DrawWireCube(col.bounds.center, col.bounds.size); } } #endif } }