代码之家  ›  专栏  ›  技术社区  ›  Jori

在uxml中带有滑块的Unity混音器,尽管使用了PlayerPrefs,但在场景重新加载后音量值不会持久

  •  0
  • Jori  · 技术社区  · 1 年前

    在Unity中,我使用混音器来管理音量,包括音乐和SFX。我已经通过UXML实现了UI滑块,并使用PlayerPrefs在会话之间保存和加载音量值。随着时间的推移,我遇到了一个问题:虽然滑块值被正确导入和显示,但重新加载场景后音量不会持续。例如,如果我将音乐音量设置为50%并重新启动场景,音量将恢复到默认值。我已经通过PlayerPrefs验证了这些值是否正确保存,但似乎混音器在重新加载场景后没有应用这些值。我尝试了几种解决方案,但到目前为止还没有成功。我该如何解决这个问题?

    using UnityEngine;
    using UnityEngine.Audio;
    using UnityEngine.UIElements;
    
    public class VolumeController : MonoBehaviour
    {
        public string sliderTemplateName = "MySlider";
        public AudioMixer musicMixer;
        public AudioMixer sfxMixer;
    
        private const string musicPrefsKey = "MusicVolume";
        private const string sfxPrefsKey = "SFXVolume";
    
        private const float minVolumeDB = -80f;
        private const float maxVolumeDB = 0f;
    
        private Slider musicSlider;
        private Slider sfxSlider;
    
        private void Awake()
        {
            Debug.Log("Awake called");
            LoadVolumeSettings();
        }
    
        private void OnEnable()
        {
            Debug.Log("OnEnable called");
    
            var uiDocument = GetComponent<UIDocument>();
            if (uiDocument != null)
            {
                var root = uiDocument.rootVisualElement;
                var sliders = root.Query<Slider>(sliderTemplateName).ToList();
    
                if (sliders.Count >= 2)
                {
                    musicSlider = sliders[0];
                    sfxSlider = sliders[1];
    
                    musicSlider.RegisterValueChangedCallback(evt => OnMusicVolumeSliderChanged(evt.newValue));
                    sfxSlider.RegisterValueChangedCallback(evt => OnSFXVolumeSliderChanged(evt.newValue));
    
                    // Initializing sliders with PlayerPrefs values
                    float savedMusicVolume = PlayerPrefs.GetFloat(musicPrefsKey, 0.5f);
                    float savedSfxVolume = PlayerPrefs.GetFloat(sfxPrefsKey, 0.5f);
    
                    musicSlider.SetValueWithoutNotify(savedMusicVolume);
                    ApplyMusicVolume(savedMusicVolume);
    
                    sfxSlider.SetValueWithoutNotify(savedSfxVolume);
                    ApplySFXVolume(savedSfxVolume);
    
                    Debug.Log($"OnEnable: Loaded music volume: {savedMusicVolume}, SFX volume: {savedSfxVolume}");
                }
                else
                {
                    Debug.LogError("Insufficient sliders found in UXML.");
                }
            }
            else
            {
                Debug.LogError("UIDocument not found on the GameObject.");
            }
        }
    
        private void OnDisable()
        {
            Debug.Log("OnDisable called");
            if (musicSlider != null)
            {
                musicSlider.UnregisterValueChangedCallback(evt => OnMusicVolumeSliderChanged(evt.newValue));
            }
            if (sfxSlider != null)
            {
                sfxSlider.UnregisterValueChangedCallback(evt => OnSFXVolumeSliderChanged(evt.newValue));
            }
        }
    
        private void LoadVolumeSettings()
        {
            Debug.Log("LoadVolumeSettings called");
    
            float musicVolume = PlayerPrefs.GetFloat(musicPrefsKey, 0.5f);
            float sfxVolume = PlayerPrefs.GetFloat(sfxPrefsKey, 0.5f);
    
            ApplyMusicVolume(musicVolume);
            ApplySFXVolume(sfxVolume);
    
            Debug.Log($"LoadVolumeSettings: Loaded music volume: {musicVolume}, SFX volume: {sfxVolume}");
        }
    
        private void OnMusicVolumeSliderChanged(float volume)
        {
            Debug.Log($"OnMusicVolumeSliderChanged: Volume changed to {volume}");
            SetMusicVolume(volume);
        }
    
        private void OnSFXVolumeSliderChanged(float volume)
        {
            Debug.Log($"OnSFXVolumeSliderChanged: Volume changed to {volume}");
            SetSFXVolume(volume);
        }
    
        private void SetMusicVolume(float volume)
        {
            PlayerPrefs.SetFloat(musicPrefsKey, volume);
            PlayerPrefs.Save();
            ApplyMusicVolume(volume);
    
            Debug.Log($"SetMusicVolume: Music volume saved and applied: {volume}");
        }
    
        private void SetSFXVolume(float volume)
        {
            PlayerPrefs.SetFloat(sfxPrefsKey, volume);
            PlayerPrefs.Save();
            ApplySFXVolume(volume);
    
            Debug.Log($"SetSFXVolume: SFX volume saved and applied: {volume}");
        }
    
        private void ApplyMusicVolume(float volume)
        {
            float musicVolumeDB = Mathf.Lerp(minVolumeDB, maxVolumeDB, volume);
            musicMixer.SetFloat("MusicVolume", musicVolumeDB);
            Debug.Log($"ApplyMusicVolume: Applied music volume: {volume} ({musicVolumeDB} dB)");
        }
    
        private void ApplySFXVolume(float volume)
        {
            float sfxVolumeDB = Mathf.Lerp(minVolumeDB, maxVolumeDB, volume);
            sfxMixer.SetFloat("SFXVolume", sfxVolumeDB);
            Debug.Log($"ApplySFXVolume: Applied SFX volume: {volume} ({sfxVolumeDB} dB)");
        }
    
        [ContextMenu("Reset PlayerPrefs")]
        private void ResetPlayerPrefs()
        {
            PlayerPrefs.DeleteKey(musicPrefsKey);
            PlayerPrefs.DeleteKey(sfxPrefsKey);
            PlayerPrefs.Save();
            Debug.Log("ResetPlayerPrefs: PlayerPrefs for music and SFX volumes have been reset.");
        }
    }
    
    

    我尝试使用PlayerPrefs在会话之间保存和加载音量值。我预计在重新加载场景后,音量将保持设置为通过PlayerPrefs保存的值。

    0 回复  |  直到 1 年前
    推荐文章