Unity编写Toggle音乐开关脚本时Music值不更新是什么原因?
问题原因
- 执行顺序逻辑错误:Update函数中你先执行了
Music = PlayerPrefs.GetInt("Music"),把公开变量Music强制覆盖为持久化存储的旧值,之后才调用MakeTextRed()根据Toggle状态修改Music变量。但修改后的值没有在当前帧存回PlayerPrefs,下一帧执行Update第一行就又被旧值覆盖,所以Inspector面板的Music变量永远显示PlayerPrefs里的旧值,看不到变化。 - 无效持久化逻辑:你在修改Music变量之前就已经执行了
PlayerPrefs.SetInt("Music", Music),相当于每次都把未更新的旧值重新写回存储,Toggle的修改完全没有同步到持久化数据里。 - 性能浪费:Toggle状态变化是事件驱动的,不需要每帧在Update里反复读写PlayerPrefs、判断状态,不仅占用性能也更容易出现逻辑顺序错误。
修正方案
推荐使用Toggle自带的状态变化事件实现功能,不需要每帧执行逻辑,修正后代码如下:
[SerializeField] Toggle toggle; [SerializeField] AudioSource audioSource; public int Music; private void Start() { // 启动时仅读取一次持久化状态,初始化Toggle和音频 Music = PlayerPrefs.GetInt("Music", 1); // 第二个参数为默认值,首次运行无存储数据时默认开启音乐 toggle.isOn = Music == 1; audioSource.enabled = Music == 1; // 绑定Toggle状态变化监听,状态修改时才触发对应逻辑 toggle.onValueChanged.AddListener(OnMusicToggleChanged); } // Toggle状态变化时自动触发 private void OnMusicToggleChanged(bool isOn) { Music = isOn ? 1 : 0; audioSource.enabled = isOn; PlayerPrefs.SetInt("Music", Music); PlayerPrefs.Save(); // 立即写入持久化存储,避免进程异常退出导致设置丢失 }
如果要保留原有Update写法的逻辑,仅调整执行顺序即可临时修复问题,但该写法性能较差不推荐长期使用:
private void Update() { // 先根据Toggle状态修改Music值 MakeTextRed(); // 再同步音频状态、写入持久化存储 audioSource.enabled = Music == 1; PlayerPrefs.SetInt("Music", Music); // 移除原有的每帧读取PlayerPrefs覆盖Music的逻辑,启动时读取一次即可 }
内容的提问来源于stack exchange,提问作者Mirazz_Boi
相关产品推荐
相关产品推荐

