在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保存的值。