using BrewMonster.Assets.PerfectWorld.Scripts.UI; using BrewMonster.Common; using BrewMonster.Managers; using BrewMonster.Scripts; using BrewMonster.Scripts.Managers; using BrewMonster.UI; using CSNetwork.GPDataType; using Cysharp.Threading.Tasks.Triggers; using PerfectWorld.Scripts.Managers; using System; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace BrewMonster { public class SettingSound : MonoBehaviour { [Header("Sound Settings")] [SerializeField] private Toggle tog_bgm; [SerializeField] private Toggle tog_sfx; [SerializeField] private Toggle tog_master; [SerializeField] private RectTransform handle_bmg; [SerializeField] private RectTransform handle_sfx; [SerializeField] private RectTransform handle_master; [SerializeField] private TextMeshProUGUI txt_bgm; [SerializeField] private TextMeshProUGUI txt_sfx; [SerializeField] private TextMeshProUGUI txt_master; [Header("Sprite")] [SerializeField] private Sprite switch_off; [SerializeField] private Sprite switch_on; [Header("Switch Config")] private float slideDuration = 0.15f; private float handleOffPositionX = -88.3f; private float handleOnPositionX = -27.8f; private float textOnPositionX = -27.8f; private float textOffPositionX = 30f; private Color textOnColor = new Color(0.96f, 0.84f, 0.61f); private Color textOffColor = new Color(0.6f, 0.6f, 0.6f); [Header("Slider")] [SerializeField] private Slider slider_bgm; [SerializeField] private Slider slider_sfx; [SerializeField] private Slider slider_master; [Header("Slider Value Level")] private float valueLevel1 = 0; private float valueLevel2 = 0.173f; private float valueLevel3 = 0.393f; private float valueLevel4 = 0.603f; private float valueLevel5 = 0.797f; private float valueLevel6 = 1f; [Header("slider Text Level")] [SerializeField] private TextMeshProUGUI txt_level_of_bgm; [SerializeField] private TextMeshProUGUI txt_level_of_sfx; [SerializeField] private TextMeshProUGUI txt_level_of_master; private Coroutine bgmCoroutine; private Coroutine sfxCoroutine; private Coroutine masterCoroutine; private void Update() { UpdateSliderText(slider_bgm, txt_level_of_bgm); UpdateSliderText(slider_sfx, txt_level_of_sfx); UpdateSliderText(slider_master, txt_level_of_master); } private void OnEnable() { UpdateSwitchInstant(tog_bgm, handle_bmg, txt_bgm); UpdateSwitchInstant(tog_sfx, handle_sfx, txt_sfx); UpdateSwitchInstant(tog_master, handle_master, txt_master); tog_bgm.onValueChanged.AddListener(OnBgmChanged); tog_sfx.onValueChanged.AddListener(OnSfxChanged); tog_master.onValueChanged.AddListener(OnMasterChanged); } private void OnDisable() { tog_bgm.onValueChanged.RemoveListener(OnBgmChanged); tog_sfx.onValueChanged.RemoveListener(OnSfxChanged); tog_master.onValueChanged.RemoveListener(OnMasterChanged); slider_bgm.onValueChanged.RemoveListener(OnBgmSliderChanged); slider_sfx.onValueChanged.RemoveListener(OnSfxSliderChanged); slider_master.onValueChanged.RemoveListener(OnMasterSliderChanged); } private void OnBgmChanged(bool isOn) { if (bgmCoroutine != null) { StopCoroutine(bgmCoroutine); } bgmCoroutine = StartCoroutine(SlideSwitchCoroutine(tog_bgm, handle_bmg, txt_bgm)); // TODO: Add logic to change BGM volume or mute state } private void OnSfxChanged(bool isOn) { if (sfxCoroutine != null) { StopCoroutine(sfxCoroutine); } sfxCoroutine = StartCoroutine(SlideSwitchCoroutine(tog_sfx, handle_sfx, txt_sfx)); // TODO: Add logic to change SFX volume or mute state } private void OnMasterChanged(bool isOn) { if (masterCoroutine != null) { StopCoroutine(masterCoroutine); } masterCoroutine = StartCoroutine(SlideSwitchCoroutine(tog_master, handle_master, txt_master)); // TODO: Add logic to change Master volume or mute state } private void OnBgmSliderChanged(float value) { UpdateSliderText(slider_bgm, txt_level_of_bgm); } private void OnSfxSliderChanged(float value) { UpdateSliderText(slider_sfx, txt_level_of_sfx); } private void OnMasterSliderChanged(float value) { UpdateSliderText(slider_master, txt_level_of_master); } private void UpdateSwitchInstant(Toggle toggle, RectTransform handle, TextMeshProUGUI statusText) { bool isOn = toggle.isOn; // Logic circle switch float handleTargetX = isOn ? handleOnPositionX : handleOffPositionX; handle.anchoredPosition = new Vector2(handleTargetX, handle.anchoredPosition.y); // Logic text switch if (statusText != null) { float textTargetX = isOn ? textOnPositionX : textOffPositionX; statusText.rectTransform.anchoredPosition = new Vector2(textTargetX, statusText.rectTransform.anchoredPosition.y); statusText.text = isOn ? "Mở" : "Tắt"; statusText.color = isOn ? textOnColor : textOffColor; } // Logic background switch if (handle.TryGetComponent(out var handleImage)) { handleImage.sprite = isOn ? switch_on : switch_off; } } private IEnumerator SlideSwitchCoroutine(Toggle toggle, RectTransform handle, TextMeshProUGUI statusText) { bool isOn = toggle.isOn; // Get info target float handleTargetX = isOn ? handleOnPositionX : handleOffPositionX; float handleStartX = handle.anchoredPosition.x; float textTargetX = isOn ? textOnPositionX : textOffPositionX; float textStartX = statusText != null ? statusText.rectTransform.anchoredPosition.x : 0f; // Update text and background immediately if (statusText != null) { statusText.text = isOn ? "Mở" : "Tắt"; statusText.color = isOn ? textOnColor : textOffColor; } if (handle.TryGetComponent(out var handleImage)) { handleImage.sprite = isOn ? switch_on : switch_off; } float time = 0f; while (time < slideDuration) { time += Time.deltaTime; float t = Mathf.Clamp01(time / slideDuration); float smoothT = Mathf.SmoothStep(0f, 1f, t); // Move handle float currentHandleX = Mathf.Lerp(handleStartX, handleTargetX, smoothT); handle.anchoredPosition = new Vector2(currentHandleX, handle.anchoredPosition.y); // Move text if (statusText != null) { float currentTextX = Mathf.Lerp(textStartX, textTargetX, smoothT); statusText.rectTransform.anchoredPosition = new Vector2(currentTextX, statusText.rectTransform.anchoredPosition.y); } yield return null; } // Position it correctly in the last frame to avoid errors. handle.anchoredPosition = new Vector2(handleTargetX, handle.anchoredPosition.y); if (statusText != null) { statusText.rectTransform.anchoredPosition = new Vector2(textTargetX, statusText.rectTransform.anchoredPosition.y); } } private void UpdateSliderText(Slider slider, TextMeshProUGUI text) { if(slider == null || text == null) return; int level = GetLevelFromValue(slider.value); text.text = $"Mức {level}"; } private int GetLevelFromValue(float value) { float t12 = (valueLevel1 + valueLevel2) * 0.5f; float t23 = (valueLevel2 + valueLevel3) * 0.5f; float t34 = (valueLevel3 + valueLevel4) * 0.5f; float t45 = (valueLevel4 + valueLevel5) * 0.5f; float t56 = (valueLevel5 + valueLevel6) * 0.5f; if(value < t12) return 1; else if(value < t23) return 2; else if(value < t34) return 3; else if(value < t45) return 4; else if(value < t56) return 5; else return 6; } } }