使用PlayerPrefs在Unity中的场景中保存audio音量

我有玩音乐的游戏。 我有一个静音切换button,当您按下它时,会将我的游戏音乐静音,当您再次按下时,它也会取消静音。 我在加载场景时遇到了保存audio的问题。 (我尝试使用DontDestoryOnLoad,但我的静音脚本附加到我的主菜单canvas,所以它也保存canvas,以及我不想要的,我发现使用playerprefs更容易)。 例如,当我点击静音button时,会使我的游戏静音,玩游戏,死亡,重新启动游戏,音量也会重新启动。 尽管我使用了playerprefs来尝试解决问题,但是它并没有奏效,但它仍然是一样的。 无论如何,这是我的脚本:

public bool mute; public static Vector3 target; void Start () { PlayerPrefs.GetFloat("mute"); } void Update() { PlayerPrefs.GetFloat("mute"); } private void Muted () { mute = !mute; if (mute) { gameObject.GetComponent<AudioSource> ().volume = 0; PlayerPrefs.SetFloat("mute", 0); } else { gameObject.GetComponent<AudioSource> ().volume = 1; PlayerPrefs.SetFloat("mute", 1); } } 

你正在更新中使用PlayerPrefs.GetFloat,这是一个可怕的想法。

我看到你已经将脚本附加到canvas上了。 相反,创建一个名为SoundManager的类。 将其附加到游戏加载到的介绍场景中的空的游戏对象。 做一个单身人士,并有一个dontdestroyonload这个gameobject。

 public class SoundManager : MonoBehaviour { public static SoundManager instance; public bool mute{ set{ PlayerPrefs.SetFloat("muted", value ? 1 : 0); } get{ return PlayerPrefs.GetFloat("muted", 0) == 0 ? false : true; } } } 

然后你可以做一个简单的检查点击切换button

 SoundManager.instance.mute != SoundManager.instance.mute; gameObject.GetComponent<AudioSource>().mute = SoundManager.instance.mute; 

首先你必须创建一个封装所有需要保存/加载的游戏状态variables的类,然后你必须用[Serializable]标记这个类,然后执行以下操作:

 [Serializable] public class GameState { public int Volume; public bool mute; } 

现在创建一个类并添加这两个方法,并且不要忘记实例化GameState并将其传递给这个类

 public class GameSave : MonoBehaviour { public GameState gm; public void SaveData() { if (!Directory.Exists("Saves")) Directory.CreateDirectory("Saves"); BinaryFormatter formatter = new BinaryFormatter(); FileStream saveFile = File.Create("Saves/save.binary"); formatter.Serialize(saveFile, GameState); saveFile.Close(); } public void LoadData() { BinaryFormatter formatter = new BinaryFormatter(); FileStream saveFile = File.Open("Saves/save.binary", FileMode.Open); gm = (GameState)formatter.Deserialize(saveFile); saveFile.Close(); } } 

如果audio静音,您没有检查和恢复。

 void Start () { if(PlayerPrefs.GetFloat("mute") == 0) { gameObject.GetComponent<AudioSource> ().volume = 0; } else { gameObject.GetComponent<AudioSource> ().volume = 1; } } 

根据Unity的文件:

https://docs.unity3d.com/ScriptReference/PlayerPrefs.GetFloat.html

public static float GetFloat(string key,float defaultValue = 0.0F);

如果存在,则返回首选项文件中对应于键的值。 如果它不存在,它将返回defaultValue。

你需要做的是使用GetFloat(key)获取已存储在PlayerPrefs中的值并将其分配给AudioSource.volume。

一般情况下,如果您的值/引用是静态的(不会被修改),您可以将它们caching在Start函数中供以后使用。 而更新function在这里完全没有必要。

作为一个例子,我重写你的代码如下所示:

 public bool mute; private AudioSource audioSource; void Start () { // at the beginning we cache the needed references and read volume value from playerPrefs audioSource = GetComponent<AudioSource> (); audioSource.volume = PlayerPrefs.GetFloat("mute",1f); // we pass 1 as default value if nothing's found } private void Mute (bool value) { mute = value; var volume = mute ? 0f: 1f; if(audioSource ) audioSource.volume = volume ; PlayerPrefs.SetFloat("mute", volume ); }