You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 09:21:00