Kursach_StealthAction/Assets/Scripts/MainMenuManager.cs

442 lines
14 KiB
C#
Raw 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.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class MainMenuManager : MonoBehaviour
{
[Header("Панели")]
public GameObject mainMenuPanel;
public GameObject headerContainer;
public GameObject settingsPanel;
public GameObject loadingPanel;
[Header("Загрузка")]
public string gameSceneName = "SampleScene";
public Slider loadingSlider;
public Text loadingText;
[Header("Настройки: Звук")]
public Slider volumeSlider;
public Text volumeValueText;
public Toggle muteToggle;
[Header("Настройки: Графика")]
public Dropdown qualityDropdown;
public Toggle fullscreenToggle;
public Dropdown resolutionDropdown;
[Header("Настройки: Управление")]
public Slider sensitivitySlider;
public Text sensitivityValueText;
private Resolution[] availableResolutions;
private List<Resolution> filteredResolutions = new List<Resolution>();
private bool isInitializing = false;
private void Awake()
{
// Разблокируем курсор и гарантируем нормальный ход времени
Time.timeScale = 1f;
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
private void Start()
{
isInitializing = true;
if (mainMenuPanel != null) mainMenuPanel.SetActive(true);
if (settingsPanel != null) settingsPanel.SetActive(false);
if (loadingPanel != null) loadingPanel.SetActive(false);
InitializeSettingsUI();
isInitializing = false;
}
#region Основное меню
public void PlayGame()
{
PlayerPrefs.SetInt("PlayIntroCutscene", 1);
PlayerPrefs.Save();
if (!string.IsNullOrEmpty(gameSceneName))
{
StartCoroutine(LoadSceneRoutine(gameSceneName));
}
else
{
SceneManager.LoadScene(1);
}
}
public void PlayPrologue()
{
PlayerPrefs.SetInt("PlayIntroCutscene", 1);
PlayerPrefs.Save();
PlayGame();
}
public void OpenSettings()
{
if (mainMenuPanel != null) mainMenuPanel.SetActive(false);
if (headerContainer != null) headerContainer.SetActive(false);
if (settingsPanel != null) settingsPanel.SetActive(true);
}
public void CloseSettings()
{
PlayerPrefs.Save();
if (settingsPanel != null) settingsPanel.SetActive(false);
if (headerContainer != null) headerContainer.SetActive(true);
if (mainMenuPanel != null) mainMenuPanel.SetActive(true);
}
public void QuitGame()
{
PlayerPrefs.Save();
Debug.Log("[MainMenu] Выход из игры вызван.");
Application.Quit();
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#endif
}
private IEnumerator LoadSceneRoutine(string sceneName)
{
if (loadingPanel != null)
{
loadingPanel.SetActive(true);
if (mainMenuPanel != null) mainMenuPanel.SetActive(false);
if (settingsPanel != null) settingsPanel.SetActive(false);
}
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
if (asyncLoad == null)
{
Debug.LogError($"[MainMenu] Не удалось запустить загрузку сцены '{sceneName}'.");
yield break;
}
asyncLoad.allowSceneActivation = false;
while (!asyncLoad.isDone)
{
float progress = Mathf.Clamp01(asyncLoad.progress / 0.9f);
if (loadingSlider != null)
{
loadingSlider.value = progress;
}
if (loadingText != null)
{
loadingText.text = $"Загрузка операции... {Mathf.RoundToInt(progress * 100)}%";
}
// Когда загрузка завершена на 90% (внутренний предел Unity до активации)
if (asyncLoad.progress >= 0.9f)
{
if (loadingText != null)
{
loadingText.text = "Инициализация локации...";
}
yield return new WaitForSecondsRealtime(0.2f);
asyncLoad.allowSceneActivation = true;
break;
}
yield return null;
}
}
#endregion
#region Настройки
private void InitializeSettingsUI()
{
// 1. Громкость и Mute
float savedVolume = PlayerPrefs.GetFloat(GameSettings.KeyMasterVolume, 1.0f);
bool savedMute = PlayerPrefs.GetInt(GameSettings.KeyIsMuted, 0) == 1;
if (volumeSlider != null)
{
volumeSlider.minValue = 0f;
volumeSlider.maxValue = 1f;
volumeSlider.value = savedVolume;
volumeSlider.onValueChanged.AddListener(OnVolumeChanged);
}
if (muteToggle != null)
{
muteToggle.isOn = savedMute;
muteToggle.onValueChanged.AddListener(OnMuteChanged);
}
UpdateVolumeLabel(savedVolume, savedMute);
AudioListener.volume = savedMute ? 0f : savedVolume;
// 2. Качество графики
if (qualityDropdown != null)
{
qualityDropdown.ClearOptions();
List<string> qualityOptions = new List<string>();
string[] names = QualitySettings.names;
// Локализованные названия или имена из проекта
for (int i = 0; i < names.Length; i++)
{
qualityOptions.Add(TranslateQualityName(names[i]));
}
qualityDropdown.AddOptions(qualityOptions);
int currentQuality = PlayerPrefs.GetInt(GameSettings.KeyQualityLevel, QualitySettings.GetQualityLevel());
currentQuality = Mathf.Clamp(currentQuality, 0, names.Length - 1);
qualityDropdown.value = currentQuality;
qualityDropdown.RefreshShownValue();
qualityDropdown.onValueChanged.AddListener(OnQualityChanged);
}
// 3. Полноэкранный режим
bool isFullscreen = PlayerPrefs.GetInt(GameSettings.KeyFullscreen, Screen.fullScreen ? 1 : 0) == 1;
if (fullscreenToggle != null)
{
fullscreenToggle.isOn = isFullscreen;
fullscreenToggle.onValueChanged.AddListener(OnFullscreenChanged);
}
// 4. Разрешения экрана
PopulateResolutions();
// 5. Чувствительность мыши
float savedSens = PlayerPrefs.GetFloat(GameSettings.KeyMouseSensitivity, 1.0f);
if (sensitivitySlider != null)
{
sensitivitySlider.minValue = 0.2f;
sensitivitySlider.maxValue = 3.0f;
sensitivitySlider.value = savedSens;
sensitivitySlider.onValueChanged.AddListener(OnSensitivityChanged);
}
UpdateSensitivityLabel(savedSens);
}
private void PopulateResolutions()
{
if (resolutionDropdown == null) return;
resolutionDropdown.ClearOptions();
availableResolutions = Screen.resolutions;
filteredResolutions.Clear();
List<string> options = new List<string>();
int currentResolutionIndex = 0;
int currentWidth = Screen.currentResolution.width;
int currentHeight = Screen.currentResolution.height;
int savedWidth = PlayerPrefs.GetInt(GameSettings.KeyResolutionWidth, currentWidth);
int savedHeight = PlayerPrefs.GetInt(GameSettings.KeyResolutionHeight, currentHeight);
// Фильтруем дубликаты разрешений (с разной частотой обновления)
HashSet<string> seen = new HashSet<string>();
for (int i = availableResolutions.Length - 1; i >= 0; i--)
{
var res = availableResolutions[i];
string key = $"{res.width}x{res.height}";
if (!seen.Contains(key))
{
seen.Add(key);
filteredResolutions.Insert(0, res);
}
}
// Если разрешений нет (например в некоторых режимах редактора), добавляем стандартные
if (filteredResolutions.Count == 0)
{
Resolution fallback = new Resolution { width = 1920, height = 1080 };
filteredResolutions.Add(fallback);
}
for (int i = 0; i < filteredResolutions.Count; i++)
{
var res = filteredResolutions[i];
string option = $"{res.width} × {res.height}";
options.Add(option);
if (res.width == savedWidth && res.height == savedHeight)
{
currentResolutionIndex = i;
}
}
resolutionDropdown.AddOptions(options);
resolutionDropdown.value = currentResolutionIndex;
resolutionDropdown.RefreshShownValue();
resolutionDropdown.onValueChanged.AddListener(OnResolutionChanged);
}
public void OnVolumeChanged(float val)
{
if (isInitializing) return;
PlayerPrefs.SetFloat(GameSettings.KeyMasterVolume, val);
bool isMuted = muteToggle != null && muteToggle.isOn;
if (!isMuted)
{
AudioListener.volume = val;
}
UpdateVolumeLabel(val, isMuted);
}
public void OnMuteChanged(bool isMuted)
{
if (isInitializing) return;
PlayerPrefs.SetInt(GameSettings.KeyIsMuted, isMuted ? 1 : 0);
float currentVol = volumeSlider != null ? volumeSlider.value : 1.0f;
AudioListener.volume = isMuted ? 0f : currentVol;
UpdateVolumeLabel(currentVol, isMuted);
}
private void UpdateVolumeLabel(float volume, bool isMuted)
{
if (volumeValueText != null)
{
if (isMuted)
{
volumeValueText.text = "ВЫКЛ";
}
else
{
volumeValueText.text = $"{Mathf.RoundToInt(volume * 100)}%";
}
}
}
public void OnQualityChanged(int index)
{
if (isInitializing) return;
QualitySettings.SetQualityLevel(index, true);
PlayerPrefs.SetInt(GameSettings.KeyQualityLevel, index);
}
public void OnFullscreenChanged(bool isFullscreen)
{
if (isInitializing) return;
Screen.fullScreen = isFullscreen;
PlayerPrefs.SetInt(GameSettings.KeyFullscreen, isFullscreen ? 1 : 0);
}
public void OnResolutionChanged(int index)
{
if (isInitializing) return;
if (index < 0 || index >= filteredResolutions.Count) return;
Resolution res = filteredResolutions[index];
bool isFullscreen = fullscreenToggle != null ? fullscreenToggle.isOn : Screen.fullScreen;
Screen.SetResolution(res.width, res.height, isFullscreen ? FullScreenMode.FullScreenWindow : FullScreenMode.Windowed);
PlayerPrefs.SetInt(GameSettings.KeyResolutionWidth, res.width);
PlayerPrefs.SetInt(GameSettings.KeyResolutionHeight, res.height);
}
public void OnSensitivityChanged(float val)
{
if (isInitializing) return;
PlayerPrefs.SetFloat(GameSettings.KeyMouseSensitivity, val);
UpdateSensitivityLabel(val);
}
private void UpdateSensitivityLabel(float val)
{
if (sensitivityValueText != null)
{
sensitivityValueText.text = $"{val:F1}x";
}
}
public void ResetToDefaults()
{
isInitializing = true;
// Сброс звука
if (volumeSlider != null) volumeSlider.value = 1.0f;
if (muteToggle != null) muteToggle.isOn = false;
AudioListener.volume = 1.0f;
PlayerPrefs.SetFloat(GameSettings.KeyMasterVolume, 1.0f);
PlayerPrefs.SetInt(GameSettings.KeyIsMuted, 0);
UpdateVolumeLabel(1.0f, false);
// Сброс графики (максимальное качество)
int highestQuality = QualitySettings.names.Length - 1;
if (qualityDropdown != null)
{
qualityDropdown.value = highestQuality;
qualityDropdown.RefreshShownValue();
}
QualitySettings.SetQualityLevel(highestQuality, true);
PlayerPrefs.SetInt(GameSettings.KeyQualityLevel, highestQuality);
// Сброс полного экрана
if (fullscreenToggle != null)
{
fullscreenToggle.isOn = true;
}
Screen.fullScreen = true;
PlayerPrefs.SetInt(GameSettings.KeyFullscreen, 1);
// Сброс разрешения (родное)
if (resolutionDropdown != null && filteredResolutions.Count > 0)
{
int lastIndex = filteredResolutions.Count - 1;
resolutionDropdown.value = lastIndex;
resolutionDropdown.RefreshShownValue();
var res = filteredResolutions[lastIndex];
Screen.SetResolution(res.width, res.height, FullScreenMode.FullScreenWindow);
PlayerPrefs.SetInt(GameSettings.KeyResolutionWidth, res.width);
PlayerPrefs.SetInt(GameSettings.KeyResolutionHeight, res.height);
}
// Сброс чувствительности
if (sensitivitySlider != null)
{
sensitivitySlider.value = 1.0f;
}
PlayerPrefs.SetFloat(GameSettings.KeyMouseSensitivity, 1.0f);
UpdateSensitivityLabel(1.0f);
PlayerPrefs.Save();
isInitializing = false;
}
private string TranslateQualityName(string unityName)
{
switch (unityName.ToLower())
{
case "very low": return "Очень низкое";
case "low": return "Низкое";
case "medium": return "Среднее";
case "high": return "Высокое";
case "very high": return "Очень высокое";
case "ultra": return "Ультра";
default: return unityName;
}
}
#endregion
}