PJ/Assets/scripts/dotfs_scripts/LevelEnvironmentManager.cs

194 lines
No EOL
5.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections; // Обязательно добавляем для работы с корутинами
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
[AddComponentMenu("Level Management/Level Environment Manager")]
public class LevelEnvironmentManager : MonoBehaviour
{
public static LevelEnvironmentManager Instance { get; private set; }
[Header("Components")]
[SerializeField] private Image _backgroundImage;
[Header("Configuration")]
[SerializeField] private LevelConfig _defaultConfig;
[SerializeField] private List<LevelExceptionSetup> _levelExceptions = new List<LevelExceptionSetup>();
[Tooltip("Группы сцен (например, для Меню или Магазинов)")]
[SerializeField] private List<LevelGroupSetup> _levelGroups = new List<LevelGroupSetup>();
[Tooltip("Настройки диапазонов с учетом префиксов")]
[SerializeField] private List<LevelRangeSetup> _levelRanges = new List<LevelRangeSetup>();
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
private void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
LevelImport.OnLevelLoaded += HandleLevelLoaded;
}
private void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
LevelImport.OnLevelLoaded -= HandleLevelLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (scene.name == "ImportLeverl") return;
StartCoroutine(HandleLevelLoadedRoutine(scene.name));
}
private IEnumerator HandleLevelLoadedRoutine(string levelName)
{
// Магия здесь: ждем окончания текущего кадра.
// Это гарантирует, что все Awake и Start на загруженной сцене завершились.
yield return null;
HandleLevelLoaded(levelName);
}
public void HandleLevelLoaded(string levelName)
{
if (Instance != this) return;
// 1. Ищем LevelImport
LevelImport levelImport = FindFirstObjectByType<LevelImport>();
List<GameObject> blocks = new List<GameObject>();
if (levelImport != null && levelImport.Blocks != null)
{
blocks = levelImport.Blocks;
}
// 2. Определяем конфиг
LevelConfig targetConfig = DetermineConfig(levelName);
// 3. Применяем конфигурацию
ApplyConfig(targetConfig, blocks);
}
public void ApplyOverrideConfig(LevelConfig manualConfig)
{
ApplyConfig(manualConfig, new List<GameObject>());
}
private LevelConfig DetermineConfig(string levelName)
{
// Исключения
foreach (var exception in _levelExceptions)
{
if (string.Equals(exception.LevelName, levelName, StringComparison.OrdinalIgnoreCase))
return exception.Config;
}
// Группы
foreach (var group in _levelGroups)
{
if (group.SceneNames == null) continue;
foreach (var name in group.SceneNames)
{
if (string.Equals(name.Trim(), levelName.Trim(), StringComparison.OrdinalIgnoreCase))
{
return group.Config;
}
}
}
// Диапазоны
foreach (var range in _levelRanges)
{
if (levelName.StartsWith(range.Prefix, StringComparison.OrdinalIgnoreCase))
{
string numericPart = levelName.Substring(range.Prefix.Length);
if (int.TryParse(numericPart, out int levelID))
{
if (levelID >= range.StartLevel && levelID <= range.EndLevel)
return range.Config;
}
}
}
// Дефолт
return _defaultConfig;
}
private void ApplyConfig(LevelConfig config, List<GameObject> blocks)
{
if (config == null) return;
if (GlobalMusicManager.Instance != null)
{
GlobalMusicManager.Instance.PlayMusic(config.BackgroundMusic);
}
else
{
Debug.LogWarning("GlobalMusicManager.Instance is null! Музыка не применена.");
}
// В Unity безопаснее проверять просто на null для уничтоженных объектов
if (_backgroundImage == null)
{
GameObject bgObj = GameObject.FindWithTag("BG");
if (bgObj != null)
{
_backgroundImage = bgObj.GetComponent<Image>();
}
}
if (_backgroundImage != null && config.BackgroundImage != null)
{
_backgroundImage.sprite = config.BackgroundImage;
}
// Вызываем события
config.OnLevelConfigApplied?.Invoke(blocks);
}
}
[Serializable]
public class LevelConfig
{
public AudioClip BackgroundMusic;
public Sprite BackgroundImage;
public UnityEngine.Events.UnityEvent<List<GameObject>> OnLevelConfigApplied;
}
[Serializable]
public class LevelGroupSetup
{
public string GroupName;
public string[] SceneNames;
public LevelConfig Config;
}
[Serializable]
public class LevelRangeSetup
{
public string Prefix = "Level";
public int StartLevel;
public int EndLevel;
public LevelConfig Config;
}
[Serializable]
public class LevelExceptionSetup
{
public string LevelName;
public LevelConfig Config;
}