音频管理类多用于音频较多,类别较多的项目中,往往又主程来写,便于程序员直接找到想要播放的音频剪辑,虽然过程稍复杂,但是便于整理和后期添加,如果一个项目在中后期要求添加另外的音效,那么采用这种管理类只需添加一个枚举值就可以了,避免很多反复修改代码的麻烦。
首先写一个可以继承的单例脚本,两种写法,所有的单例类都去继承它,省去七行代码,常用于单例脚本比较多的项目中。
1.继承自Monobehaviour
using UnityEngine;
using System.Collections;
//继承MonoBehaviour 的单例模版,别的脚本可以直接用,省去七行代码
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
#region 单例
private static T instance;
public static T Instance {
get {
if (instance == null) {
GameObject obj = new GameObject (typeof(T).Name);
instance = obj.AddComponent<T> ();
}
return instance;
}
}
#endregion
//可重写的Awake虚方法,用于实例化对象
protected virtual void Awake ()
{
instance = this as T;
}
}
2.不继承Monobehaviour的单例
using UnityEngine;
using System.Collections;
public abstract class Singleton<T> : System.IDisposable where T : new()
{
private static T instance;
public static T Instance {
get {
if (instance == null) {
instance = new T ();
}
return instance;
}
}
public virtual void Dispose ()
{
}
}
所有音乐名称的枚举列表
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//所有音乐名称的枚举列表
public class MusicType {
public enum Feeds
{
BuyItem,
Feed01,
Feed02,
PlankUpFeed,
SetPlankFeed,
PlankUpFeed2,
PutFeed,
ManDead,
WomanDead,
TimeBack,
FallingFeed,
JumpFeed,
UIFeed,
}
public enum Items
{
Ach,
BGMusic01,
BGMusic02,
BGMusic03,
}
public enum Main
{
Accomplish,
BGMusic,
Select,
Unlock,
Bgm,
}
public enum Monsters
{
BigBoss,
Fat141,
Fat142,
Fat143,
}
public enum Towers
{
Anchor,
Arrow,
}
}
然后是写一个可以直接通过音频名字查找路径,并动态加载的单例脚本,相当于资源加载类,其他的资源也可以用它来完成加载
using UnityEngine;
using System.Collections;
// 通过用户传递进来的枚举值, 自动的分析出该枚举值对应的资源在哪个路径下.
public class ResourcesMgr : Singleton<ResourcesMgr>
{
// 面向用户的方法: 方法名<T>指定类型
/// <summary>
/// 返回用户需要的资源.
/// </summary>
/// <param name="enumName">Enum name.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public T Load<T> (object enumName) where T : Object
{
// 获取枚举类型的字符串形式
string enumType = enumName.GetType ().Name;
//空的字符串
string filePath = string.Empty;
switch (enumType) {
case "Feeds":
{
filePath = "Music/Feeds/" + enumName.ToString ();
break;
}
case "Items":
{
filePath = "Music/Items/" + enumName.ToString ();
break;
}
case "Main":
{
filePath = "Music/Main/" + enumName.ToString ();
break;
}
case "Monsters":
{
filePath = "Music/Monsters/" + enumName.ToString ();
break;
}
case "Towers":
{
filePath = "Music/Towers/" + enumName.ToString ();
break;
}
case "WinType":
{
filePath = "UIWin/" + enumName.ToString ();
break;
}
default:
{
break;
}
}
return Resources.Load<T> (filePath);
}
}
最后是音频管理脚本
using UnityEngine;
using System.Collections;
//音乐管理类,继承单例类
public class MusicMgr : MonoSingleton<MusicMgr>
{
// 用于播放背景音乐的音乐源
private AudioSource m_bgMusic;
// 用于播放音效的音乐源
private AudioSource m_effectMusic;
// 控制背景音乐音量大小
public float BgVolume
{
get
{
return m_bgMusic.volume;
}
set
{
m_bgMusic.volume = value;
}
}
//控制音效音量的大小
public float EffectVolmue
{
get
{
return m_effectMusic.volume;
}
set
{
m_effectMusic.volume = value;
}
}
private bool _isPlayEffect = true;
//重写虚方法
protected override void Awake()
{
base.Awake();
//实例化音乐源
m_bgMusic = gameObject.AddComponent<AudioSource>();
m_bgMusic.loop = true; //开启循环
m_bgMusic.playOnAwake = false; //开始播放
//实例化音乐源
m_effectMusic = gameObject.AddComponent<AudioSource>();
m_effectMusic.loop = true;
m_effectMusic.playOnAwake = false;
}
private void Start()
{
if (Config.Instance.isOnBg)
{
m_bgMusic.Play();
}
else
{
m_bgMusic.Pause();
}
_isPlayEffect = Config.Instance.isOnEffect ? true : false;
BgVolume = Config.Instance.volume;
EffectVolmue = Config.Instance.volume;
}
// 播放背景音乐,传进一个音频剪辑的name
private void PlayBgBase(object bgName, bool restart = false)
{
//定义一个空的字符串
string curBgName = string.Empty;
//如果这个音乐源的音频剪辑不为空的话
if (m_bgMusic.clip != null)
{
//得到这个音频剪辑的name
curBgName = m_bgMusic.clip.name;
}
// 根据用户的音频片段名称, 找到AuioClip, 然后播放,
//ResourcesMgr是提前定义好的查找音频剪辑对应路径的单例脚本,并动态加载出来
AudioClip clip = ResourcesMgr.Instance.Load<AudioClip>(bgName);
//如果找到了,不为空
if (clip != null)
{
//如果这个音频剪辑已经复制给类音频源,切正在播放,那么直接跳出
if (clip.name == curBgName && !restart)
{
return;
}
//否则,把改音频剪辑赋值给音频源,然后播放
m_bgMusic.clip = clip;
m_bgMusic.Play();
}
else
{
//没找到直接报错
// 异常, 调用写日志的工具类.
UnityEngine.Debug.Log("没有找到音频片段");
}
}
//播放各种音频剪辑的调用方法,MusicType是提前写好的存放各种音乐名称的枚举类,便于外面直接调用
public void PlayBg(MusicType.Feeds bgName, bool restart = false)
{
PlayBgBase(bgName, restart);
}
public void PlayBg(MusicType.Items bgName, bool restart = false)
{
PlayBgBase(bgName, restart);
}
public void PlayBg(MusicType.Main bgName, bool restart = false)
{
PlayBgBase(bgName, restart);
}
public void PlayBg(MusicType.Monsters bgName, bool restart = false)
{
PlayBgBase(bgName, restart);
}
public void PlayBg(MusicType.Towers bgName, bool restart = false)
{
PlayBgBase(bgName, restart);
}
// 播放音效
private void PlayEffectBase(object effectName, bool defAudio = true, float volume = 1f)
{
if (!_isPlayEffect)
{
return;
}
//根据查找路径加载对应的音频剪辑
AudioClip clip = ResourcesMgr.Instance.Load<AudioClip>(effectName);
//如果为空的话,直接报错,然后跳出
if (clip == null)
{
UnityEngine.Debug.Log("没有找到音效片段");
return;
}
//否则,就是clip不为空的话,如果defAudio=true,直接播放
if (defAudio)
{
//PlayOneShot (音频剪辑, 音量大小)
m_effectMusic.PlayOneShot(clip, volume);
}
else
{
//指定点播放
AudioSource.PlayClipAtPoint(clip, Camera.main.transform.position, volume);
}
}
//播放各种音频剪辑的调用方法,MusicType是提前写好的存放各种音乐名称的枚举类,便于外面直接调用
public void PlayEffect(MusicType.Feeds effectName, bool defAudio = true, float volume = 1f)
{
PlayEffectBase(effectName, defAudio, volume);
}
public void PlayEffect(MusicType.Items effectName, bool defAudio = true, float volume = 1f)
{
PlayEffectBase(effectName, defAudio, volume);
}
public void PlayEffect(MusicType.Main effectName, bool defAudio = true, float volume = 1f)
{
PlayEffectBase(effectName, defAudio, volume);
}
public void PlayEffect(MusicType.Monsters effectName, bool defAudio = true, float volume = 1f)
{
PlayEffectBase(effectName, defAudio, volume);
}
public void PlayEffect(MusicType.Towers effectName, bool defAudio = true, float volume = 1f)
{
PlayEffectBase(effectName, defAudio, volume);
}
public void StopEffect() {
m_effectMusic.Stop();
m_effectMusic.clip = null;
}
public void StopBg()
{
m_bgMusic.Stop();
m_bgMusic.clip = null;
}
//暂停
public void PauseBgMusic() {
m_bgMusic.Pause();
}
//回复
public void ResumeBgMusic() {
m_bgMusic.Play();
}
public void PauseEffect()
{
_isPlayEffect = false;
}
public void ResumeEffect()
{
_isPlayEffect = true;
}
}
在工程中建一个空物体GameController,此脚本直接挂在空物体上
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour
{
void Start()
{
UIManager.GetInstance().PushPanel(UIPanelType.SignPanel);
}
void Update()
{
MusicMgr.Instance.PlayBg(MusicType.Main.Bgm);
//MusicMgr.Instance.PlayEffect(MusicType.Towers.Anchor);
}
实例如下此管理类非原创