游戏世界里离不开各种酷炫的音效,把这些音效集中起来进行管理是每个项目必须要做的事情. 分享一下自用的SoundMgr(适用于大多Unity项目)
整体思路:
SoundMgr脚本被调用时,自动执行继承的 _onInit()方法,new一个 SoundMgr,并进行初始化.
1 创建一个单例类.
using UnityEngine;
using System.Collections;
public class Singleton<T> where T : class, new()
{
private static object _syncobj = new object();
public static volatile T _Instance = null;
public static T Get()
{
if (_Instance == null)
{
lock (_syncobj)
{
if (_Instance == null)
{
_Instance = new T();
}
}
}
return _Instance;
}
protected Singleton()
{
_onInit();
}
virtual protected void _onInit() { }
}
2 SoundMgr继承该单例类.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SoundMgr : Singleton<SoundMgr>
{
public bool enabled
{
get { return _bEnabled; }
set
{
_bEnabled = value;
if (_bEnabled == false)
{
StopAllSounds();
}
}
}
protected bool _bEnabled;
protected const int MAX_SOURCE = 20;
protected AudioSource[] _arrSources;
protected float _fDefaultVol = 0.5f;
protected Dictionary<string, AudioClip> _audioClips;
public void LoadSounds(string path)
{
var clips = Resources.LoadAll<AudioClip>(path);
foreach (var clip in clips)
{
_audioClips.Add(clip.name, clip);
}
}
public void UnloadAllSounds()
{
_audioClips.Clear();
StopAllSounds();
Resources.UnloadUnusedAssets();
}
public void SetVolume(int i, float newVol)
{
try
{
_arrSources[i].volume = newVol;
}
catch (System.Exception e)
{
Debug.LogWarning(e.Message);
}
}
public void SetVolume(AudioClip c, float newVol)
{
for (int i = 0; i < _arrSources.Length; i++)
{
AudioSource s = _arrSources[i];
if (s.clip == c)
{
s.volume = newVol;
}
}
}
public void SetVolume(string soundName, float newVol)
{
AudioClip ac = GetClip(soundName);
for (int i = 0; i < _arrSources.Length; i++)
{
AudioSource s = _arrSources[i];
if (s.clip == ac)
{
s.volume = newVol;
}
}
}
public int PlayClip(string soundName, bool loop = false)
{
Debug.Assert(_audioClips.ContainsKey(soundName));
AudioClip clip = _audioClips[soundName];
return PlayClip(clip, loop);
}
public int PlayClip(string soundName, float vol, bool loop = false)
{
Debug.Assert(_audioClips.ContainsKey(soundName));
AudioClip clip = _audioClips[soundName];
return PlayClip(clip, vol, loop);
}
public AudioClip GetClip(string soundName)
{
Debug.Assert(_audioClips.ContainsKey(soundName));
AudioClip clip = _audioClips[soundName];
return clip;
}
public int PlayClip(AudioClip c, bool loop = false)
{
Debug.Assert(c != null);
if (!_bEnabled) return -1;
for (int i = 0; i < _arrSources.Length; i++)
{
AudioSource s = _arrSources[i];
if (!s.isPlaying)
{
s.clip = c;
s.loop = loop;
s.Play();
SetVolume(i, _fDefaultVol);
return i;
}
}
return -1;
}
public int PlayClip(AudioClip c, float vol, bool loop = false)
{
Debug.Assert(c != null);
if (!_bEnabled) return -1;
for (int i = 0; i < _arrSources.Length; i++)
{
AudioSource s = _arrSources[i];
if (!s.isPlaying)
{
s.clip = c;
s.loop = loop;
s.Play();
SetVolume(i, vol);
return i;
}
}
return -1;
}
public int PlayClip(AudioClip c, int mask, bool loop)
{
if (!_bEnabled) return -1;
for (int i = 0; i < _arrSources.Length; i++)
{
if ((mask & (1 << i)) > 0 && !_arrSources[i].isPlaying)
{
_arrSources[i].clip = c;
_arrSources[i].loop = loop;
_arrSources[i].Play();
//SetVolume(i, 1.0f);
return i;
}
}
return -1;
}
public void StopClip(AudioClip c)
{
foreach (AudioSource s in _arrSources)
{
if (s.clip == c && s.isPlaying)
{
s.Stop();
s.clip = null;
}
}
}
public void StopAllSounds()
{
for (int i = 0; i < _arrSources.Length; i++)
{
_arrSources[i].Stop();
_arrSources[i].clip = null;
}
}
public void StopChannel(int i)
{
_arrSources[i].Stop();
}
public void PauseChannel(int i)
{
if (_arrSources[i].isPlaying)
_arrSources[i].Pause();
}
public void ResumeChannel(int i)
{
if (!_arrSources[i].isPlaying)
_arrSources[i].UnPause();
}
private void _init(GameObject gameObject)
{
_bEnabled = true;
if (gameObject.GetComponent<AudioListener>() == null) gameObject.AddComponent<AudioListener>();
_arrSources = new AudioSource[MAX_SOURCE];
for (int i = 0; i < _arrSources.Length; i++)
{
_arrSources[i] = (AudioSource)gameObject.AddComponent(typeof(AudioSource));
}
_audioClips = new Dictionary<string, AudioClip>();
soundMgrGmObj = gameObject;
}
public GameObject soundMgrGmObj = null;
////设置播放音量大小
public void ChangeValue(float newValue)
{
for (int i = 0; i < _arrSources.Length; i++)
{
SetVolume(i, newValue);
}
}
public void SetActive(bool bFlag)
{
AudioListener.volume = bFlag ? 1 : 0;
}
override protected void _onInit()
{
var soundMgrGameObj = new GameObject("SoundMgr");
GameObject.DontDestroyOnLoad(soundMgrGameObj);
_init(soundMgrGameObj);
}
}
3 SoundName脚本, 对应音频文件的名字. 音频文件放在Resources/SoundRes 文件夹下.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundName
{
public const string BackGround1 = "BG1";
public const string BackGround2 = "BG2";
}
4 Unity工程里新建一个SoundObject
Start() 方法里添加如下代码
void Start()
{
SoundMgr.Get().LoadSounds("SoundRes");
Destroy(this.gameObject);
SoundMgr.Get().PlayClip(SoundName.BG2, true);
}
5 常用方法:
设置音量: SoundMgr.Get().ChangeValue(1.0f);
播放声音: SoundMgr.Get().PlayClip(“BG1”);
循环播放: SoundMgr.Get().PlayClip(“BG1”,true);
停止播放所有声音: SoundMgr.Get().StopAllSounds();
获取某个声音: SoundMgr.Get().GetClip(SoundName.BackGround2);
停止播放某个声音:
SoundMgr.Get().StopClip(SoundMgr.Get().GetClip(SoundName.BG1));