Unity实现 场景切换 音乐不断

本文介绍如何在Unity中实现不同场景间的背景音乐连续播放而不断档的方法。通过使用DontDestroyOnLoad确保音频源跨场景存在,并利用GUI按钮控制音乐播放状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自彪哥,我稍微略加改动下。。把我自己实现过程中容易犯错的点稍微点下。红字需注意

http://blog.youkuaiyun.com/xiebiao360/article/details/14093463

 

原文如下:

 

今天有人问我切换场景时背景音乐不能正常播放,于是写了个例子简单测试下,具体如下:

首先创建两个场景,为了区分两个场景(test1.unity & test2.unity)的不同,我们给第一个场景中加一个Cube(可以不建),并新建一个空物体GameObject,附加音频组件AudioSource,拖放音频文件上去,为保证这个空物体在场景切换时不被销毁,我们需要使用DontDestroyOnLoad(object)方法,新建一个C#脚本TestAudio

 

[csharp]  view plain copy
 
  1. using UnityEngine;  
  2. using System.Collections;    
  3. public class TestAudio : MonoBehaviour {    
  4.     void Start () {  
  5.     DontDestroyOnLoad(this.gameObject);  
  6.     }        
  7. }  

 

将此脚本拖放给GameObject,保持GameObject不被Destory掉

二、

再建一个C#脚本TestAudio2,用来绘制GUI进行切换场景

 

这里我直接贴出我的TestAudio2(我的起名叫audioXieBiao.cs)全部代码图如下

 

using UnityEngine;
using System.Collections;

public class audioXieBiao : MonoBehaviour {
     public GameObject objPrefabInstantSource;//文章中叫obje
     public GameObject musicInstant = null;//文章中叫obj
	// Use this for initialization
	void Start () {
        musicInstant = GameObject.FindGameObjectWithTag("sound");
        if (musicInstant==null)
        {
            musicInstant = (GameObject)Instantiate(objPrefabInstantSource);
        }
	}
    void OnGUI()
    {
        if (GUILayout.Button("Load Level"))
        {
            if (Application.loadedLevelName == "test1")//关于这个下面有详细介绍
            {
                Application.LoadLevel("test2");
            }
            else
            {
                Application.LoadLevel("test1");
            }
        }
        if (GUI.Button(new Rect(10, 90, 120, 30), "Pause"))
        {
            musicInstant.audio.Pause();
        }
        if (GUI.Button(new Rect(10, 130, 120, 30), "Stop"))
        {
            musicInstant.audio.Stop();
        }
        if (GUI.Button(new Rect(10, 50, 120, 30), "Play"))
        {
            musicInstant.audio.Play();
        }
    }
}

 

 

 

 

 

[csharp]  view plain copy
 
  1. if (GUI.Button(new Rect(10,10,120,30),"load level")) {  
  2.     if (Application.loadedLevelName=="test1") {  
  3.         Application.LoadLevel("test2");  
  4.     }  
  5.     else {  
  6.         Application.LoadLevel("test1");  
  7.     }  
  8. }  

在这里我们拖放给相机就可以了
另外要注意一个地方,当我们从第一个场景test1切换到test2的时候没有问题,但是从test2切换回test1的时候,场景里会多出一个GameObject,此时会出现两个声音(一个是test1里重新生成的,另一个是我们之前没有销毁的),为了解决这个问题我们把GameObject设为预设,并加个标签sound

编辑TestAudio2中的代码

 

[csharp]  view plain copy
 
  1. public GameObject obje;  
  2. GameObject obj=null;  
  3. // Use this for initialization  
  4. void Start () {  
  5.     obj = GameObject.FindGameObjectWithTag("sound");  
  6.     if (obj==null) {  
  7.         obj = (GameObject)Instantiate(obje);  
  8.     }     
  9. }  

拖放Project中的预设GameObject到obje(此时hierarchy中只有cube和camera)

 

 

运行,切换场景时,背景音乐不间断播放

接下来可以对背景音乐进行控制,如播放,暂停,停止

 

[csharp]  view plain copy
 
  1. if (GUI.Button(new Rect(10,90,120,30),"Pause")) {  
  2.     obj.audio.Pause();  
  3. }  
  4. if (GUI.Button(new Rect(10,130,120,30),"Stop")) {  
  5.     obj.audio.Stop();  
  6. }  
  7. if (GUI.Button(new Rect(10,50,120,30),"Play")) {  
  8.     obj.audio.Play();  
  9. }  

 

 

 

附加学习:如何获得场景名称 

检验结果为下:

 

输出为:

 

 

 

  //如何当前场景名称 方法一
        Debug.Log("方法一:" + Application.loadedLevelName);//当所在为test1.unity时,输出test1,当所在为test2.unity时,输出test2.
        //方法二
        string currentSceneName = UnityEditor.EditorApplication.currentScene;//这样输出的是Assert目录下的完整目录:Assets/Scenes/test1.unity
        Debug.Log("currentSceneName输出为:"+currentSceneName);
        string[] nameS= currentSceneName.Split('/');
        Debug.Log("方法一:" + nameS[nameS.Length - 1]);//始终显示test1.unity()

 

 

 

 

 

### Unity3D 中实现背景音乐场景播放的方法 为了实现Unity3D 中让背景音乐能够跨越多个场景持续播放而不中断,可以采用以下几种常见的方式: #### 方法一:利用 `DontDestroyOnLoad` 函数 通过创建一个专门用于管理全局背景音乐游戏对象,并将其标记为不会随着场景切换而销毁。具体操作如下: 1. 创建一个新的游戏对象(GameObject),并命名为 `GlobalMusicManager` 或类似的名称。 2. 向该对象添加组件 `AudioSource` 并配置其音频剪辑(Audio Clip)。确保启用循环选项 (`Loop`) 来保持音乐连续播放[^1]。 3. 编写一段简单的脚本来控制此对象的行为,在脚本中调用 `DontDestroyOnLoad(this.gameObject)` 防止它在新场景加载时被移除。 以下是对应的 C# 脚本示例代码: ```csharp using UnityEngine; public class GameMusic : MonoBehaviour { private static GameObject instance; void Awake() { if (instance == null) { instance = this.gameObject; DontDestroyOnLoad(instance); } else if (instance != this.gameObject) { Destroy(gameObject); // 如果已经有实例存在,则删除当前新建的对象以防重复 } } } ``` #### 方法二:检测现有 Global Music 对象的存在状态 为了避免多次进入不同场景后不断新增相同的背景音效源造成混乱或者声音叠加现象发生,可以在每个单独的场景里都放置好预设好的 Audio Source 组件,但在初始化阶段先检查整个项目运行期间是否已经有了负责处理全局 BGM 的实体;如果没有发现的话才允许继续执行创建动作[^2]。 这种方法的优点在于更加灵活可控同时也减少了不必要的资源消耗。下面给出了一段伪逻辑描述来帮助理解这一过程的工作原理: 当某个特定的新 Level 开始载入之前... - 查找名为 "GlobalUIMusic" 的节点是否存在; - 若找到则什么都不做直接沿用之前的设置即可; - 反之就按照既定模板重新生成一份新的实例出来供后续使用直到程序结束为止。 --- ### 总结说明 以上两种方式都可以有效地解决 Unity 游戏开发过程中遇到关于如何维持背景旋律贯穿于各个独立部分之间的问题。开发者可以根据实际需求选择适合自己的解决方案实施应用到作品当中去。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值