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

Unity返回主菜单时音频重叠问题求助及代码排查

Unity 2020:返回主菜单时关卡与菜单背景音乐重叠问题

问题场景

  • 主菜单场景通过空对象添加Audio Source组件实现背景音乐播放
  • 关卡场景同样使用空对象+Audio Source,并附加脚本通过DontDestroyOnLoad保证关卡切换时音乐不中断
  • 从关卡返回主菜单时,关卡音乐未停止,与主菜单音乐同时播放,自行编写的脚本未解决该问题

原代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManager;

public class DontDestroyAudio : MonoBehaviour
{
     void Awake() 
    {
        if(SceneManager.GetActiveScene().name == "MainMenu")
        {
            Destroy(this.gameObject);
            Debug.Log("This if statment works?");
        }

        else
        {
            DontDestroyOnLoad(transform.gameObject);
        }
    }
}

问题分析

原脚本逻辑存在核心缺陷:

  • 该脚本挂在关卡音乐对象上,当关卡音乐被DontDestroyOnLoad保留后,切换回主菜单时,该对象的Awake方法不会再次触发,因此判断主菜单场景并销毁自身的逻辑根本不会执行
  • 主菜单场景加载时会创建自己的音乐对象,加上残留的关卡音乐对象,导致双轨播放

解决方案

方案1:改进关卡音乐脚本,监听场景切换事件

修改关卡音乐的脚本,通过单例模式确保唯一实例,并监听场景切换来控制音乐启停:

using UnityEngine;
using UnityEngine.SceneManagement;

public class DontDestroyAudio : MonoBehaviour
{
    private static DontDestroyAudio _instance;

    void Awake()
    {
        // 单例模式:确保全局只有一个关卡音乐实例
        if (_instance == null)
        {
            _instance = this;
            DontDestroyOnLoad(gameObject);
            // 注册场景加载完成事件监听
            SceneManager.sceneLoaded += OnSceneLoaded;
        }
        else
        {
            // 如果已有实例,销毁当前重复对象
            Destroy(gameObject);
        }
    }

    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        AudioSource audioSource = GetComponent<AudioSource>();
        if (scene.name == "MainMenu")
        {
            // 切换到主菜单时停止关卡音乐
            audioSource.Stop();
        }
        else
        {
            // 切换到关卡场景时,若音乐未播放则启动
            if (!audioSource.isPlaying)
            {
                audioSource.Play();
            }
        }
    }

    void OnDestroy()
    {
        // 注销事件监听,避免内存泄漏
        SceneManager.sceneLoaded -= OnSceneLoaded;
    }
}

方案2:为主菜单音乐添加辅助脚本(可选,增强稳定性)

给主菜单的音乐对象附加以下脚本,确保进入主菜单时自动停止残留的关卡音乐:

using UnityEngine;

public class MainMenuAudio : MonoBehaviour
{
    void Awake()
    {
        // 查找关卡音乐实例并停止
        DontDestroyAudio levelAudio = FindObjectOfType<DontDestroyAudio>();
        if (levelAudio != null)
        {
            AudioSource levelSource = levelAudio.GetComponent<AudioSource>();
            if (levelSource.isPlaying)
            {
                levelSource.Stop();
            }
        }
        // 启动主菜单音乐
        GetComponent<AudioSource>().Play();
    }
}

注意事项

  • 确保主菜单的Audio Source组件勾选了Play On Awake(或者通过脚本手动播放)
  • 关卡场景的Audio Source同样根据需求设置Play On Awake,或者通过脚本控制启动

内容的提问来源于stack exchange,提问作者GoEvan101New

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 03:23:18