日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于Unity中的声音管理模块(专题七)

發布時間:2023/12/13 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于Unity中的声音管理模块(专题七) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

聲音的要素

1: 音頻文件AudioClip
2: 音源AudioSource;
3: 耳朵AudioListener;//全局只能有一個
4: 2D/3D音頻;//2D只是簡單地播放聲音,3D可以根據距離衰減音量

怎樣聽到聲音:

創建一個節點,掛載AudioSource組件,AudioSource組件關聯AudioClip屬性,設置聲音是否一開始就加載播放play on awake,是否循環播放,2D還是3D

場景中有一個節點有AudioListener組件,掛載AudioListener組件的節點在掛載AudioSource組件節點的聲音范圍內。運行,可以聽到聲音。

?

?

音樂與音效管理

1: 游戲里面一般分為音樂與音效;
2: 音樂指的是游戲的背景音樂;
3: 音效是游戲中的較短的音樂,來配合游戲的動作等;
4: Unity游戲沒有音樂和音效之分,都是AudioSource + AudioClip;
5: 2D音效沒有衰減,所以與位置沒有關系;
6: 3D音效需要有聲音所在節點的位置;
7: 游戲需求需要音樂和音效分開設置,開啟和關閉;

?

?

sound_manager腳本

首先,聲音包括音樂和音效,我們分兩大塊來管理,音樂為一塊,音效為一塊,這個塊實際上Unity內部是不分的,但是我們來分,

用字典數據類型保存URL和音源AudioSource之間的對應關系,兩個表,一個是音樂的,一個是音效的。

有了這兩個表,這樣如果我們要禁止背景音樂就去遍歷音樂表,如果我們要禁止音效就去遍歷音效表。

播放一個音效,需要new一個物體,在這個物體上加音源AudioSource組件,關聯好音頻文件AudioClip,這樣就會播放出一個音效,

播放出來的音效會有分2D和3D,2D隨便放在哪里,3D需要管理,有一個位置,所以加一個播放3D音效的接口。

1: 全局唯一的sound_manager;
2: 在場景里面創建一個物體(做為聲音的根節點),而且設置這個物體場景切換也不會刪除;
3: 編寫接口播放背景音樂play_music;
4: 編寫接口播放背景音效play_effect; // 2D聲音
5: 音樂和音效內部實現都是一樣的, 只不過要把url分組管理, 音效為一組,音樂為一組;
6: 提供開關音效接口set_mute(),并將值寫入本地,下一次打開游戲的時候會讀取這個值,維持上一次的設置。
7: 提供開關背景音樂接口switch_music(),并將值寫入本地,下一次打開游戲的時候會讀取這個值,維持上一次的設置。
8: 添加一個play_effect接口在指定的坐標出訪一個聲音, 可以用于3D音效;
9: 添加一個接口停止掉背景音樂stop_music(url);
10: 添加一個接口刪除掉播放的背景音樂clear_music(url), clear_effect(url);
11: 聲音文件來自Resouce還是assetBundle,可以通過資源管理來封裝,目前從Resource里面加載;
12: 加一個腳本,每隔0.5秒掃描一次已經播放完的聲音組件,將它disable;

?

?

聲音管理實例

1.創建Unity項目工程和文件目錄,保存場景

2.在Resources文件夾下創建一個sounds文件夾,把背景音樂Login.mp3和音效Close.mp3(第70)放進去

3.為了統一管理游戲中的聲音,寫一個腳本sound_manager來管理

 打開sound_manager.cs,初始化sound_manager

using System.Collections; using System.Collections.Generic; using UnityEngine;public class sound_manager {// (1) 聲音根節點的物體;// (2) 保證這個節點在場景切換的時候不會刪除,這樣就不用再初始化一次;// (3) 所有播放聲音的生源節點,都是在這個節點下static GameObject sound_play_object;//這個就是根節點// url --> AudioSource 映射, 區分音樂,音效static Dictionary<string, AudioSource> musics=null;//音樂表static Dictionary<string, AudioSource> effects = null;//音效表public static void init(){sound_play_object = new GameObject("sound_play_object");//初始化根節點GameObject.DontDestroyOnLoad(sound_play_object);//場景切換的時候不會刪除根節點//初始化音樂表和音效表musics = new Dictionary<string, AudioSource>();effects = new Dictionary<string, AudioSource>();} }

?

4.創建一個空節點,下面掛載一個腳本game_scene來測試音樂和音效

 打開game_scene.cs,寫一個語句測試初始化

using System.Collections; using System.Collections.Generic; using UnityEngine;public class game_scene : MonoBehaviour {// Use this for initializationvoid Start () {sound_manager.init();//初始化音樂音效管理 }// Update is called once per framevoid Update () {} }

?

5.運行,初始化,節點如下

?

6.接下來開始寫背景音樂和音效的接口

 打開sound_manager.cs

using System.Collections; using System.Collections.Generic; using UnityEngine;public class sound_manager {// (1) 聲音根節點的物體;// (2) 保證這個節點在場景切換的時候不會刪除,這樣就不用再初始化一次;// (3) 所有播放聲音的生源節點,都是在這個節點下static GameObject sound_play_object;//這個就是根節點static bool is_music_mute = false;//存放當前全局背景音樂是否靜音的變量static bool is_effect_mute = false;//存放當前音效是否靜音的變量// url --> AudioSource 映射, 區分音樂,音效static Dictionary<string, AudioSource> musics=null;//音樂表static Dictionary<string, AudioSource> effects = null;//音效表//初始化public static void init(){sound_play_object = new GameObject("sound_play_object");//初始化根節點sound_play_object.AddComponent<sound_scan>();//把聲音檢測組件掛載到根節點下GameObject.DontDestroyOnLoad(sound_play_object);//場景切換的時候不會刪除根節點//初始化音樂表和音效表musics = new Dictionary<string, AudioSource>();effects = new Dictionary<string, AudioSource>();// 從本地來加載這個開關if (PlayerPrefs.HasKey("music_mute"))//判斷is_music_mute有沒有保存在本地 {int value = PlayerPrefs.GetInt("music_mute");is_music_mute = (value == 1);//int轉換bool,如果value==1,返回true,否則就是false }// 從本地來加載這個開關if (PlayerPrefs.HasKey("effect_mute"))//判斷is_effect_mute有沒有保存在本地 {int value = PlayerPrefs.GetInt("effect_mute");is_effect_mute = (value == 1);//int轉換bool,如果value==1,返回true,否則就是false }}//播放指定背景音樂的接口public static void play_music(string url, bool is_loop = true){AudioSource audio_source = null;if (musics.ContainsKey(url))//判斷是否已經在背景音樂表里面了 {audio_source = musics[url];//是就直接賦值過去 }else//不是就新建一個空節點,節點下再新建一個AudioSource組件 {GameObject s = new GameObject(url);//創建一個空節點s.transform.parent = sound_play_object.transform;//加入節點到場景中 audio_source = s.AddComponent<AudioSource>();//空節點添加組件AudioSourceAudioClip clip = Resources.Load<AudioClip>(url);//代碼加載一個AudioClip資源文件audio_source.clip = clip;//設置組件的clip屬性為clipaudio_source.loop = is_loop;//設置組件循環播放audio_source.playOnAwake = true;//再次喚醒時播放聲音audio_source.spatialBlend = 0.0f;//設置為2D聲音 musics.Add(url, audio_source);//加入到背景音樂字典中,下次就可以直接賦值了 }audio_source.mute = is_music_mute;audio_source.enabled = true;audio_source.Play();//開始播放 }//停止播放指定背景音樂的接口public static void stop_music(string url){AudioSource audio_source = null;if (!musics.ContainsKey(url))//判斷是否已經在背景音樂表里面了 {return;//沒有這個背景音樂就直接返回 }audio_source = musics[url];//有就把audio_source直接賦值過去audio_source.Stop();//停止播放 }//停止播放所有背景音樂的接口public static void stop_all_music(){foreach (AudioSource s in musics.Values){s.Stop();}}//刪除指定背景音樂和它的節點public static void clear_music(string url){AudioSource audio_source = null;if (!musics.ContainsKey(url))//判斷是否已經在背景音樂表里面了 {return;//沒有這個背景音樂就直接返回 }audio_source = musics[url];//有就把audio_source直接賦值過去musics[url] = null;//指定audio_source組件清空GameObject.Destroy(audio_source.gameObject);//刪除掉掛載指定audio_source組件的節點 }//切換背景音樂靜音開關public static void switch_music(){// 切換靜音和有聲音的狀態is_music_mute = !is_music_mute;//把當前是否靜音寫入本地int value = (is_music_mute) ? 1 : 0;//bool轉換intPlayerPrefs.SetInt("music_mute", value);// 遍歷所有背景音樂的AudioSource元素foreach (AudioSource s in musics.Values){s.mute = is_music_mute;//設置為當前的狀態 }}//當我的界面的靜音按鈕要顯示的時候,到底是顯示關閉,還是開始狀態;public static bool music_is_off(){return is_music_mute;}//接下來開始是音效的接口//播放指定音效的接口public static void play_effect(string url, bool is_loop = false){AudioSource audio_source = null;if (effects.ContainsKey(url))//判斷是否已經在音效表里面了 {audio_source = effects[url];//是就直接賦值過去 }else//不是就新建一個空節點,節點下再新建一個AudioSource組件 {GameObject s = new GameObject(url);//創建一個空節點s.transform.parent = sound_play_object.transform;//加入節點到場景中 audio_source = s.AddComponent<AudioSource>();//空節點添加組件AudioSourceAudioClip clip = Resources.Load<AudioClip>(url);//代碼加載一個AudioClip資源文件audio_source.clip = clip;//設置組件的clip屬性為clipaudio_source.loop = is_loop;//設置組件循環播放audio_source.playOnAwake = true;//再次喚醒時播放聲音audio_source.spatialBlend = 0.0f;//設置為2D聲音 effects.Add(url, audio_source);//加入到音效字典中,下次就可以直接賦值了 }audio_source.mute = is_effect_mute;audio_source.enabled = true;audio_source.Play();//開始播放 }//停止播放指定音效的接口public static void stop_effect(string url){AudioSource audio_source = null;if (!effects.ContainsKey(url))//判斷是否已經在音效表里面了 {return;//沒有這個背景音樂就直接返回 }audio_source = effects[url];//有就把audio_source直接賦值過去audio_source.Stop();//停止播放 }//停止播放所有音效的接口public static void stop_all_effect(){foreach (AudioSource s in effects.Values){s.Stop();}}//刪除指定音效和它的節點public static void clear_effect(string url){AudioSource audio_source = null;if (!effects.ContainsKey(url))//判斷是否已經在音效表里面了 {return;//沒有這個音效就直接返回 }audio_source = effects[url];//有就把audio_source直接賦值過去effects[url] = null;//指定audio_source組件清空GameObject.Destroy(audio_source.gameObject);//刪除掉掛載指定audio_source組件的節點 }//切換音效靜音開關public static void switch_effect(){// 切換靜音和有聲音的狀態is_effect_mute = !is_effect_mute;//把當前是否靜音寫入本地int value = (is_effect_mute) ? 1 : 0;//bool轉換intPlayerPrefs.SetInt("effect_mute", value);// 遍歷所有音效的AudioSource元素foreach (AudioSource s in effects.Values){s.mute = is_effect_mute;//設置為當前的狀態 }}//當我的界面的靜音按鈕要顯示的時候,到底是顯示關閉,還是開始狀態;public static bool effect_is_off(){return is_effect_mute;}//播放3D的音效public static void play_effect3D(string url, Vector3 pos, bool is_loop = false){AudioSource audio_source = null;if (effects.ContainsKey(url)){audio_source = effects[url];}else{GameObject s = new GameObject(url);s.transform.parent = sound_play_object.transform;s.transform.position = pos;//3D音效的位置 audio_source = s.AddComponent<AudioSource>();AudioClip clip = Resources.Load<AudioClip>(url);audio_source.clip = clip;audio_source.loop = is_loop;audio_source.playOnAwake = true;audio_source.spatialBlend = 1.0f; // 3D音效 effects.Add(url, audio_source);}audio_source.mute = is_effect_mute;audio_source.enabled = true;audio_source.Play();}//優化策略接口public static void disable_over_audio(){//遍歷背景音樂表foreach(AudioSource s in musics.Values){if (!s.isPlaying)//判斷是否在播放 {s.enabled = false;//不在播放就直接隱藏 }}//遍歷音效表foreach (AudioSource s in effects.Values){if (!s.isPlaying)//判斷是否在播放 {s.enabled = false;//不在播放就直接隱藏 }}}}

?

7.在game_scene腳本里面寫測試語句,測試接口是否可以使用

 打開game_scene.cs

using System.Collections; using System.Collections.Generic; using UnityEngine;public class game_scene : MonoBehaviour {// Use this for initializationvoid Start () {sound_manager.init();//初始化音樂音效管理//sound_manager.play_music("sounds/Login");//播放背景音樂//this.InvokeRepeating("test_music_mute", 1, 3); sound_manager.play_effect("sounds/Close");//播放音效if (sound_manager.effect_is_off())//如果當前是靜音,就切換成有聲音的狀態 {sound_manager.switch_effect();}this.InvokeRepeating("again", 3, 3);//每隔3秒調用一次//this.InvokeRepeating("test_effect_mute", 1, 3); }//背景音樂靜音切換測試函數void test_music_mute(){Debug.Log("test_music_mute");sound_manager.switch_music();}//音效靜音切換測試函數void test_effect_mute(){Debug.Log("test_effect_mute");sound_manager.switch_effect();}//隱藏AudioSource組件優化測試函數void again(){sound_manager.play_effect("sounds/Close");}// Update is called once per framevoid Update () {} }

?

8.還有一個問題就是,在某個聲音播放完成的時候,可以隱藏AudioSource組件,這樣就不會去調用組件的相關接口,游戲性能就能有所提升,這個接口在第6步已經寫好了,測試語句也在第7步顯現出來了,現在就寫一個掃描的腳本

 可以創建一個腳本sound_scan來檢測哪些聲音已經播放完成,播完的節點就把它的AudioSource組件隱藏,這個腳本0.5s啟動一次去檢測聲音節點。  

 打開sound_scan.cs

using System.Collections; using System.Collections.Generic; using UnityEngine;public class sound_scan : MonoBehaviour {// Use this for initializationvoid Start () {//固定一個節奏去掃描,每隔0.5s掃描一次this.InvokeRepeating("scan",0, 0.5f);}// Update is called once per framevoid Update () {}//定時器函數void scan(){sound_manager.disable_over_audio();//調用隱藏AudioSource組件接口 } }

9.運行時的節點

播放背景音樂時

?

播放音效時

?

?

?

注意:

Unity代碼加載資源文件的時候是沒有文件后綴名的,看到什么名字就是什么名字

轉載于:https://www.cnblogs.com/HangZhe/p/7326308.html

總結

以上是生活随笔為你收集整理的关于Unity中的声音管理模块(专题七)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 噜噜av| 中文字幕第十一页 | 欧美69视频 | 国产精品69av | 免费毛片一级 | 日韩在线视频在线观看 | 欧美美女网站 | 日韩一区二区三区不卡视频 | 亚洲精品乱码久久久久久 | 日本h在线观看 | 夜夜爽爽 | 美女131爽爽爽 | 亚洲精品乱码久久久久99 | 国产一区二区三区四区hd | 国产精品欧美久久久久久 | 亚洲色图1 | 欧美国产精品一区二区 | 欧美日韩免费一区 | 浪漫樱花在线观看高清动漫 | 在线看国产精品 | 国产盗摄一区二区三区在线 | 大伊人网 | 香蕉一区二区三区四区 | 欧美激情视频一区二区三区在线播放 | 91社区福利 | 久久久久亚洲精品中文字幕 | 四虎精品在线 | 欧美激情综合五月色丁香 | 日韩二区 | 最近高清中文在线字幕在线观看 | 人妻少妇偷人精品久久久任期 | 国产在线视频网站 | 91久久免费| 毛片视频网站在线观看 | 自拍偷拍导航 | 伊人黄色 | 老鸭窝成人 | 久久一区国产 | 青春草在线视频观看 | 伊人久久久久久久久久久久 | 久久久久亚洲AV成人网人人小说 | 成人香蕉视频 | 中国老熟妇自拍hd发布 | 天天操天天透 | 久久久精品人妻av一区二区三区 | 国产亚洲一区二区在线 | 无码aⅴ精品一区二区三区浪潮 | 依依综合网 | 日韩视频在线观看 | 欧美成人精品一区二区 | 艳妇乳肉豪妇荡乳av | 韩国性经典xxxxhd | 国模福利视频 | av综合久久 | 久久国产精品99久久人人澡 | 亚洲第一福利网站 | 在线国产中文字幕 | 美日韩视频 | 欧美一区一区 | 熟女人妻一区二区三区免费看 | 久久91亚洲 | 成人作爱视频 | 天堂av在线免费观看 | 男阳茎进女阳道视频大全 | 欧美日韩99 | 午夜成人在线视频 | 国产高清成人久久 | 精品国产精品国产偷麻豆 | 国产又大又黄视频 | av黄色免费在线观看 | 国产三级在线观看视频 | 国产精品久久久久久久久免费软件 | 在线观看高清视频 | 黄瓜视频在线观看污 | 人人搞人人插 | 天堂在线免费视频 | 中文av免费观看 | 欧美丰满熟妇xxxx | 潘金莲三级野外 | 婷婷激情六月 | 午夜黄色福利视频 | 轻轻色在线观看 | 国产女人和拘做受视频免费 | 欧美丰满熟妇xxxx | 人妻精品一区一区三区蜜桃91 | 亚洲爆爽av | 女生高潮视频在线观看 | 日本欧美激情 | 99精品欧美 | 国产成人欧美一区二区三区的 | 波多野结衣家庭主妇 | 国产婷婷色一区二区 | 亚洲高清视频一区二区 | 国产精品无码中文 | 四虎影视免费永久观看在线 | 精品影院 | www.色com | 中文字幕在线播放日韩 | 无码人妻一区二区三区精品视频 |