基于Unity3D的声音管理系统的实现

声音和音效在一个项目中是不可缺少的一部分,如下我将带领大家在Unity3D中实现一个简单的声音管理系统。功能如下:

1.利用对象池生成AudioSource对象;(对对象池不了解的童鞋,戳这里http://blog.csdn.net/YongshuangZhao/article/details/78462604

2.开放一个统一的AudioMgr接口实现声音音量和开关的控制;

3.AduioMgr可跨场景使用。

代码如下:

AudioMgr管理声音类

所以声音都由此类生成

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;

//声音对象池
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) {  
			AlllocateInstance();  
		}  
		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 (AudioMgr._instance.transform);
		instance.SetActive(false);  
		pool.Add(instance);  
		return instance;  
	}  
}

public class AudioMgr : MonoBehaviour
{
    //单例模式
	public static AudioMgr _instance;

    //audioClip列表
    public List<AudioClip> audioList;
	//初始声音预设数量
	public int initAudioPrefabCount=5;
	//记录静音前的音量大小
	[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 AudioObjectPool audioObjectPool;

    void Awake()
    {
        _instance = this;
		DontDestroyOnLoad (this);
    }

    void Start()
	{
		SceneManager.sceneUnloaded += scene => {
			StopAllCoroutines ();
			for (int i = 0; i < transform.childCount; i++) {
				if (transform.GetChild(i).hideFlags != HideFlags.HideInHierarchy) {
					InitAudioSource(transform.GetChild(i).GetComponent<AudioSource> ());
					audioObjectPool.ReleaseInstance (transform.GetChild(i).gameObject);
				}
			}
		};
		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);
		}
    }
	//暂停播放
	public void PauseAudio(AudioSource audioSource){
		audioSource.Pause ();
	}
	//继续播放
	public void ResumeAudio(AudioSource audioSource){
		audioSource.UnPause ();
	}
    //停止播放
    public void StopAudio(AudioSource audioSource)
    {
        audioSource.Stop();
    }
    //播放声音
	public void PlayAudio(AudioSource audioSource, string audioName,float volume=1, bool isLoop = false)
    {
		if (IsMute)
        {
            return;
        }
        AudioClip audioClip;
        if (audioDic.TryGetValue(audioName, out audioClip))
        {
            audioSource.loop = isLoop;
            audioSource.clip = audioClip;
			audioSource.volume = volume;
            if (audioSource.isPlaying)
            {
                audioSource.Stop();
            }
            audioSource.Play();
        }
    }
	public void PlayAudio(Vector3 audioPos, string audioName,float volume=1, bool isLoop = false)
    {
		if (IsMute)
        {
            return;
        }
        AudioClip audioClip;
        if (audioDic.TryGetValue(audioName, out audioClip))
        {
			GameObject audioGo = audioObjectPool.GetInstance();
            audioGo.transform.position = audioPos;
			audioGo.name = audioName;
            AudioSource audioSource = audioGo.GetComponent<AudioSource>();
            audioSource.clip = audioClip;
			audioSource.volume = volume;
            audioSource.loop = isLoop;
			audioSource.Play();
			StartCoroutine(DestroyAudioGo(audioSource, audioClip.length));
        }
    }
	//初始化AudioSource
	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";
	}
    //销毁声音
	IEnumerator DestroyAudioGo(AudioSource audioSource, float delayTime)
    {
		yield return new WaitForSeconds (delayTime);
		InitAudioSource (audioSource);
		audioObjectPool.ReleaseInstance (audioSource.gameObject);
    }
	void Destroy(){
		StopAllCoroutines ();
	}
}
客户端

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class AudioUI : MonoBehaviour {
	public static AudioUI _instance;

	//音量大小
	private Slider slider;
	//声音开关
	private Toggle toggle;

	void Awake(){
		_instance = this;
	}
	void Start(){
		slider = transform.Find ("Slider").GetComponent<Slider> ();
		toggle = transform.Find ("Toggle").GetComponent<Toggle> ();

		slider.onValueChanged.AddListener(
			value=>{
				AudioMgr._instance.VolumeScale=value;
			}
		);
		toggle.onValueChanged.AddListener (
			bState => {
				AudioMgr._instance.IsMute = bState;
			}
		);
	}
	void Update(){
		if (Input.GetMouseButtonDown (0)) {
			AudioMgr._instance.PlayAudio (transform.position, "audio");
		}
	}
}
运行结果如图



  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值