Unity实现音频播放管理器
更新时间:2020年12月8日 11:35 点击:1970
本文实例为大家分享了Unity实现音频播放管理器的具体代码,供大家参考,具体内容如下
1、模块化,直接用。创建一个空物体,把此脚本拖上去,然后把需要播放的所有音频拖到面板上的”AudioList“中;
2、通过AudioManagerP._instance直接调用方法,包含:
- 暂停;
- 继续播放;
- 停止播放;
- 播放背景音乐(0号播放器专用于播放背景音);
- 直接播放声音(带参数1、播放器序号 2、音频的名字 3、声音大小 4、 是否循环);
- 直接播放呻吟(带参数1、播放器序号 2、音频的名字);
- 声音淡入(带参数1、播放器序号 2、音频的名字 3、 是否循环);
- 声音淡出(带参数 播放器序号 )。
优点:同时可以播放很多个声音源,可以精确控制每个播放源的状态
缺点:不知道。
源码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AudioManagerP : MonoBehaviour { public static AudioManagerP _instance;//单例 private bool isOut; private bool isIn; void Awake() { _instance = this; DontDestroyOnLoad(this); } //audioClipl列表 public List<AudioClip> audioList; //初始声音预设数量 private int initAudioPrefabcount = 7; //记录静音前的音量大小 [HideInInspector] public float tempVolume = 0; //是否静音 private bool isMute = false; public bool IsMute { set { isMute = value; if (isMute) { tempVolume = AudioListener.volume; AudioListener.volume = 0; } else { AudioListener.volume = tempVolume; } } private get { return isMute; } } //声音大小系数 private float volumeScale = 1; public float VolumeScale { set { volumeScale = Mathf.Clamp01(value); if (!IsMute) { AudioListener.volume = value; } } private get { return volumeScale; } } //audio字典 private Dictionary<string, AudioClip> audioDic = new Dictionary<string, AudioClip>(); //背景音乐 private AudioSource bgAudioSource; //声音对象池 private AudioObjectPool audioObjectPool; private void Start() { GameObject audioPrefab = new GameObject("AudioObjectPool"); audioPrefab.AddComponent<AudioSource>(); audioPrefab.GetComponent<AudioSource>().playOnAwake = false; audioObjectPool = new AudioObjectPool(audioPrefab, initAudioPrefabcount); audioPrefab.hideFlags = HideFlags.HideInHierarchy; audioPrefab.transform.SetParent(this.transform); foreach (AudioClip ac in audioList) { audioDic.Add(ac.name, ac); } bgAudioSource = this.transform.GetChild(0).GetComponent<AudioSource>(); } private void Update() { //测试代码 if (Input.GetMouseButtonDown(0)) { //StartCoroutine(AudioFadeIn(0, "沈木-Sold Out(热播版)", true)); //音乐渐入 //PlayAudio(0, "沈木-Sold Out(热播版)"); //直接播放 } if (Input.GetMouseButtonDown(1)) { //StartCoroutine(AudioFadedOut(0)); //音乐淡出 } } /// <summary> /// 音频播放 /// </summary> /// <param name="index">播放器序号(用第几个AudioSource播放)</param> public void PauseAudio(int index) { AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); audioSource.Pause(); } /// <summary> /// 继续播放 /// </summary> /// <param name="index">播放器序号</param> public void ResumeAudio(int index) { AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); audioSource.UnPause(); } /// <summary> /// 停止播放声音 /// </summary> /// <param name="index">播放器序号</param> public void StopAudio(int index) { AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); audioSource.Stop(); } /// <summary> /// 播放背景音乐,这里直接固定0号播放器用来播放北京音乐 /// </summary> /// <param name="audioNme"></param> public void PlayBGMAudio(string audioNme) { AudioClip audioClip; if (audioDic.TryGetValue(audioNme, out audioClip)) { bgAudioSource.gameObject.SetActive(true); bgAudioSource.clip = audioClip; this.transform.GetChild(0).gameObject.SetActive(true); bgAudioSource.Play(); bgAudioSource.loop = true; } } /// <summary> /// 直接播放声音 /// </summary> /// <param name="index">播放器序号</param> /// <param name="audioName">音频文件名称</param> /// <param name="volume">音量大小</param> /// <param name="isLoop">是否循环</param> public void PlayAudio(int index, string audioName, float volume = 1, bool isLoop = false) { //Debug.Log("------------执行播放声音----------------"); AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); if (IsMute || audioSource == null) { return; } StopAllCoroutines(); AudioClip audioClip; if (audioDic.TryGetValue(audioName, out audioClip)) { //Debug.Log("按钮点击的clip名字是:"+audioClip.name); audioSource.gameObject.SetActive(true); audioSource.loop = isLoop; audioSource.clip = audioClip; audioSource.volume = volume; if (audioSource.isPlaying) { audioSource.Stop(); } audioSource.Play(); } } /// <summary> /// 重载播放,只有播放器和音频 /// </summary> /// <param name="index">播放器序号</param> /// <param name="audioName">音频的名称</param> public void PlayAudio(int index, string audioName) { //Debug.Log("------------执行播放声音----------------"); AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); if (IsMute || audioSource == null) { return; } StopAllCoroutines(); AudioClip audioClip; if (audioDic.TryGetValue(audioName, out audioClip)) { //Debug.Log("按钮点击的clip名字是:"+audioClip.name); audioSource.gameObject.SetActive(true); audioSource.clip = audioClip; if (audioSource.isPlaying) { audioSource.Stop(); } audioSource.Play(); } } /// <summary> /// 声音淡入 /// </summary> /// <param name="index">播放器序号</param> /// <param name="audioName">音频名称</param> /// <param name="isLoop">是否循环</param> /// <returns></returns> public IEnumerator AudioFadeIn(int index, string audioName, bool isLoop) { float initVolume = 0; float preTime = 1.0f / 5; //渐变率 AudioClip audioClip; if (audioDic.TryGetValue(audioName, out audioClip)) { AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); if (audioSource == null) yield break; audioSource.gameObject.SetActive(true); //声音播放对象默认为false,播放时把对应的对象设为true audioSource.clip = audioClip; audioSource.volume = 0; audioSource.loop = isLoop; print("zhi 0"); if (audioSource.isPlaying) { audioSource.Stop(); } audioSource.Play(); audioSource.volume = 0; while (true) { initVolume += 1 * Time.deltaTime * preTime; //声音渐高 audioSource.volume = initVolume; //将渐高变量赋值给播放器音量 if (initVolume >= 1 - 0.02f) //如果很接近配置文件中的值,那么将其固定在配置文件中的值(最大值) { audioSource.volume = 1; break; } yield return 1; } } } /// <summary> /// 声音淡出 /// </summary> /// <param name="index">淡出的播放器序号</param> /// <returns></returns> public IEnumerator AudioFadedOut(int index) { AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); if (audioSource == null || audioSource.volume == 0 || audioSource == null) { yield break; } float initVolume = audioSource.volume; float preTime = 1.0f / 5; while (true) { initVolume += -1 * Time.deltaTime * preTime; audioSource.volume = initVolume; if (initVolume <= 0) { audioSource.volume = 0; audioSource.Stop(); break; } yield return 1; } } /// <summary> /// 初始化音频 /// </summary> /// <param name="audioSource"></param> private void InitAudioSource(AudioSource audioSource) { if (audioSource == null) { return; } if (audioSource.isPlaying) { audioSource.Stop(); } audioSource.playOnAwake = false; audioSource.loop = false; audioSource.volume = 1; audioSource.clip = null; audioSource.name = "AudioObjectPool"; } private void Destroy() { StopAllCoroutines(); } } #region 声音对象池 /*声音对象池,待完善,可能存在同一时间多种声音源在播放,硬切或者播放完毕再切,无法判定是那种,无法准确释放AudioObjectPool 这里只是在开局使用对象池生成了指定个数的播放器,没有用到获取和释放播放器对象*/ public class AudioObjectPool { //要生成的对象池预设 private GameObject prefab; //对象池列表 private List<GameObject> pool; //构造函数 public AudioObjectPool(GameObject prefab, int initialSize) { this.prefab = prefab; this.pool = new List<GameObject>(); for (int i = 0; i < initialSize; i++) { //进行初始化 AllLocateInstance(); } } //获取实例 public GameObject GetInstance() { if (pool.Count == 0) { //创建实例 } GameObject instance = pool[0]; pool.RemoveAt(0); instance.SetActive(true); return instance; } //释放实力 public void ReleaseInstance(GameObject instance) { instance.SetActive(false); pool.Add(instance); } //生成本地实力 private GameObject AllLocateInstance() { GameObject instance = (GameObject)GameObject.Instantiate(prefab); instance.transform.SetParent(AudioManagerP._instance.transform); instance.SetActive(false); pool.Add(instance); return instance; } } #endregion
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
上一篇: 详解c# 切片语法糖
相关文章
- 这篇文章主要为大家详细介绍了Unity时间戳的使用方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要介绍了详解Howler.js Web音频播放终极解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-24
Unity中 ShaderGraph 实现旋涡传送门效果入门级教程(推荐)
通过Twirl 旋转节点对Gradient Noise 梯度噪声节点进行操作,就可得到一个旋转的旋涡效果。具体实现代码跟随小编一起通过本文学习下吧...2021-07-11- 本文主要介绍了4种延时执行的方法,主要包括Update计时器,Invoke,协程,DoTween,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-07-07
- 这篇文章主要为大家详细介绍了Unity shader实现遮罩效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要介绍了unity 判断鼠标是否在哪个UI上的两种实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
- 这篇文章主要为大家详细介绍了Unity实现换装系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-04-11
- 这篇文章主要给大家介绍了关于利用unity代码C#封装为dll的相关资料,文中通过图文将实现的方法介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 这篇文章主要为大家详细介绍了Unity Shader实现径向模糊效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-09
- 这篇文章主要介绍了unity 实现摄像机绕某点旋转一周,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
- 这篇文章主要为大家详细介绍了Unity实现截图功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要介绍了Unity中EventTrigger的几种使用操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
- 这篇文章主要为大家详细介绍了Unity Shader实现2D水流效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要介绍了Unity 按钮添加OnClick事件操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
- 这篇文章主要为大家详细介绍了Unity使用EzySlice实现模型多边形顺序切割,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-11-03
- 这篇文章主要为大家详细介绍了Unity Shader实现描边OutLine效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity Shader实现裁切效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了unity实现车方向盘转动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity实现汽车前后轮倒车轨迹计算,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-13
- 这篇文章主要介绍了Unity 点击UI与点击屏幕冲突的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10