feat(settings): implement settings UI with event handling and update methods

This commit is contained in:
Данил Ярош 2025-11-07 17:04:48 +03:00
parent 98d5285b46
commit f84f868c82
7 changed files with 36652 additions and 6 deletions

View File

@ -5,6 +5,7 @@ using UnityEngine;
using RR.Game2D.Core.Managers;
using RR.Common.Behaviour.ScriptableObjects;
using UnityEngine.Events;
namespace RR.Common.Managers
{
@ -17,8 +18,8 @@ namespace RR.Common.Managers
private const string SETTINGS_FILE_NAME = "settings.json";
private string SettingsFilePath => Path.Combine(Application.persistentDataPath, SETTINGS_FILE_NAME);
public Action OnSettingsLoaded;
public Action OnSettingsSaved;
public event Action OnSettingsLoaded;
public event Action OnSettingsSaved;
public void Initialize()
{

View File

@ -76,13 +76,13 @@ namespace RR.Common.UI
}
}
struct LevelEntry { public string name; public int world; public int stage; }
private struct LevelEntry { public string name; public int world; public int stage; }
/// <summary>
/// Метод для перебора уровней в игре
/// </summary>
/// <returns>LevelEntry - текущий мир при переборе</returns>
IEnumerable<LevelEntry> EnumerateLevelScenesInBuild()
private static IEnumerable<LevelEntry> EnumerateLevelScenesInBuild()
{
int n = SceneManager.sceneCountInBuildSettings;
for (int i = 0; i < n; i++)
@ -111,7 +111,7 @@ namespace RR.Common.UI
/// <param name="to">Конечная прозрачнеость</param>
/// <param name="time">Время перехода</param>
/// <param name="onDone">Действие при выполнении перехода</param>
IEnumerator Fade(float from, float to, float time, System.Action onDone = null)
private IEnumerator Fade(float from, float to, float time, System.Action onDone = null)
{
if (!canvasGroup) { onDone?.Invoke(); yield break; }
float t = 0f;
@ -128,7 +128,7 @@ namespace RR.Common.UI
onDone?.Invoke();
}
void Update()
private void Update()
{
// ESC закрыть
if (gameObject.activeSelf && close.action.WasPressedThisFrame())

View File

@ -1,18 +1,114 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;
using UnityEngine.EventSystems;
using RR.Common.Managers;
using RR.Game2D.Core.Managers;
using RR.Common.Behaviour.ScriptableObjects;
namespace RR.Common.UI
{
[RequireComponent(typeof(CanvasGroup), typeof(SettingsUIList))]
public class SettingsUI : MonoBehaviour
{
[Header("Управление")]
[SerializeField] private InputActionReference triggerKey;
[SerializeField] private Button saveButton;
[Header("UI")]
[SerializeField] private CanvasGroup canvasGroup;
[SerializeField] private Transform content;
[SerializeField] private float fadeDuration = 0.15f;
SettingsUIList settingsUIList;
private SettingsManager settingsManager;
private GameSettings currentSettings;
private void Awake()
{
settingsManager = SettingsManager.Instance;
if (settingsManager == null)
{
GameManager.Logger.LogError(name, "SettingsManager is null!");
return;
}
settingsManager.OnSettingsLoaded += UpdateSettings;
settingsManager.OnSettingsSaved += SaveSettingsHandler;
currentSettings = settingsManager.GetCurrentGameSettings();
if (saveButton) saveButton.onClick.AddListener(SaveAndClose);
gameObject.SetActive(false);
}
public void Open()
{
gameObject.SetActive(true);
StopAllCoroutines();
StartCoroutine(Fade(0f, 1f, fadeDuration));
}
private void Close()
{
}
private void Save()
{
}
public void SaveAndClose()
{
Save();
Close();
}
private void UpdateSettings()
{
settingsUIList = content.GetComponent<SettingsUIList>();
if (settingsUIList != null)
{
settingsUIList.UpdateSettings(settingsManager.GetCurrentGameSettings());
}
}
private void SaveSettingsHandler()
{
GameManager.Logger.Log(name, "Saved settings");
}
/// <summary>
/// Метод для плавного перехода (затухания)
/// </summary>
/// <param name="from">Начальная прозрачность</param>
/// <param name="to">Конечная прозрачнеость</param>
/// <param name="time">Время перехода</param>
/// <param name="onDone">Действие при выполнении перехода</param>
private IEnumerator Fade(float from, float to, float time, System.Action onDone = null)
{
if (!canvasGroup) { onDone?.Invoke(); yield break; }
float t = 0f;
canvasGroup.alpha = from;
canvasGroup.blocksRaycasts = true;
while (t < time)
{
t += Time.unscaledDeltaTime;
canvasGroup.alpha = Mathf.Lerp(from, to, t / time);
yield return null;
}
canvasGroup.alpha = to;
canvasGroup.blocksRaycasts = to > 0.99f;
onDone?.Invoke();
}
}
}

View File

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using RR.Common.Behaviour.ScriptableObjects;
using RR.Common.Managers;
using RR.Game2D.Core.Managers;
using UnityEngine;
using UnityEngine.UI;
namespace RR.Common.UI
{
public class SettingsUIList : MonoBehaviour
{
public List<Selectable> settingsList = new();
[Header("Настройки")]
// Fullscreen
[SerializeField] private Toggle fullscreenToggle;
// Volume
[SerializeField] private Slider musicVolumeSlider;
[SerializeField] private Slider sfxVolumeSlider;
// Payment
[SerializeField] private Toggle freeGameToggle;
[SerializeField] private Toggle givingPrizesToggle;
// Player
[SerializeField] private Slider startLivesSlider;
[SerializeField] private Slider increasedLivesSlider;
[SerializeField] private Toggle resetLivesToggle;
private SettingsManager settingsManager;
private GameSettings currentSettings;
private void Awake()
{
settingsManager = SettingsManager.Instance;
if (settingsManager == null)
{
GameManager.Logger.LogError(name, "SettingsManager is null!");
return;
}
settingsList.Add(fullscreenToggle);
settingsList.Add(musicVolumeSlider);
settingsList.Add(sfxVolumeSlider);
settingsList.Add(freeGameToggle);
settingsList.Add(givingPrizesToggle);
settingsList.Add(startLivesSlider);
settingsList.Add(increasedLivesSlider);
settingsList.Add(resetLivesToggle);
currentSettings = settingsManager.GetCurrentGameSettings();
AddListeners();
UpdateSettings(currentSettings);
}
public void UpdateSettings(GameSettings newSettings)
{
if (newSettings != null) currentSettings = newSettings;
RemoveListeners();
fullscreenToggle.isOn = currentSettings.isFullscreen;
musicVolumeSlider.value = currentSettings.musicVolume;
sfxVolumeSlider.value = currentSettings.sfxVolume;
freeGameToggle.isOn = currentSettings.isFreeGame;
givingPrizesToggle.isOn = currentSettings.isGivingPrizes;
startLivesSlider.value = currentSettings.startLivesCount;
increasedLivesSlider.value = currentSettings.livesIncreasedByCredits;
resetLivesToggle.isOn = currentSettings.setLivesToDefaultAfterFirstLose;
AddListeners();
}
private void AddListeners()
{
fullscreenToggle.onValueChanged.AddListener(settingsManager.SetFullscreen);
musicVolumeSlider.onValueChanged.AddListener(settingsManager.SetMusicVolume);
sfxVolumeSlider.onValueChanged.AddListener(settingsManager.SetSfxVolume);
freeGameToggle.onValueChanged.AddListener(settingsManager.SetIsFreeGame);
givingPrizesToggle.onValueChanged.AddListener(settingsManager.SetIsGivingPrizes);
startLivesSlider.onValueChanged.AddListener(value => settingsManager.SetStartLivesCount((int)(value / 10)));
increasedLivesSlider.onValueChanged.AddListener(value => settingsManager.SetLivesIncreasedByCredits((int)(value / 10)));
resetLivesToggle.onValueChanged.AddListener(settingsManager.SetSetLivesToDefaultAfterFirstLose);
}
private void RemoveListeners()
{
fullscreenToggle.onValueChanged.RemoveListener(settingsManager.SetFullscreen);
musicVolumeSlider.onValueChanged.RemoveListener(settingsManager.SetMusicVolume);
sfxVolumeSlider.onValueChanged.RemoveListener(settingsManager.SetSfxVolume);
freeGameToggle.onValueChanged.RemoveListener(settingsManager.SetIsFreeGame);
givingPrizesToggle.onValueChanged.RemoveListener(settingsManager.SetIsGivingPrizes);
startLivesSlider.onValueChanged.RemoveListener(value => settingsManager.SetStartLivesCount((int)(value / 10)));
increasedLivesSlider.onValueChanged.RemoveListener(value => settingsManager.SetLivesIncreasedByCredits((int)(value / 10)));
resetLivesToggle.onValueChanged.RemoveListener(settingsManager.SetSetLivesToDefaultAfterFirstLose);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 98f414c07d2f47e794d25468e8519ba7
timeCreated: 1762519929

36437
Assets/_Recovery/0 (5).unity Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: fa0cc7aabc3ce124e9fefec4607c9d6b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: