Unity3D 音频管理类

各种管理类---音频管理
简介:
音频管理类多用于音频较多,类别较多的项目中,往往又主程来写,便于程序员直接找到想要播放的音频剪辑,虽然过程稍复杂,但是便于整理和后期添加,如果一个项目在中后期要求添加另外的音效,那么采用这种管理类只需添加一个枚举值就可以了,避免很多反复修改代码的麻烦。
首先写一个可以继承的单例脚本,两种写法,所有的单例类都去继承它,省去七行代码,常用于单例脚本比较多的项目中。
(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 ()
{

}
}

(3)所有音乐名称的枚举列表,这个时必须要写的,不要嫌麻烦,如果嫌麻烦,网上有许多大神写的获得某个文件下所有列表的插件,大家可以查一下,如果代码基础比较好的话,利用终端一样可以获得所有列表,在这里就不过多的介绍了。
这是我的工程里面的所有的音频

//所有音乐名称的枚举列表
public class MusicType
{
public enum Feeds
{
BuyItem,
Feed01,
Feed02,
GiftBox01,
GiftBox02,
GiftBox03,
PetChange01,
PetChange02,
PetSound00,
PetSound01,
PetSound02,
PetSound03,
PetSound10,
PetSound11,
PetSound12,
}

public enum Items
{
Ach,
BGMusic01,
BGMusic02,
BGMusic03,
BGMusic06,
BGMusic11,
BGMusic12,
CountDown,
Crash,
CutWhale,
Finalwave,
GO,
Lose,
MC,
MenuSelect,
Object,
Perfect,
SelectFault,
ShootSelect,
TowerBulid,
TowerDeselect,
TowerSelect,
TowerSell,
TowerUpdata,
bomb,
carrot1,
carrot2,
carrot3,
clock,
}

public enum Main
{
Accomplish,
BGMusic,
Select,
Unlock,
}

public enum Monsters
{
BigBoss,
Fat141,
Fat142,
Fat143,
Fat241,
Fat242,
Fat243,
Fat341,
Fat342,
Fat343,
Fat641,
Fat642,
Fat643,
Fly151,
Fly152,
Fly161,
Fly162,
Fly163,
Fly251,
Fly252,
Fly253,
Fly261,
Fly262,
Fly263,
Fly351,
Fly352,
Fly361,
Fly362,
Fly363,
Fly651,
Fly652,
Fly653,
Fly661,
Fly662,
Fly663,
Land111,
Land112,
Land113,
Land121,
Land122,
Land131,
Land132,
Land133,
Land211,
Land221,
Land222,
Land231,
Land232,
Land311,
Land312,
Land321,
Land322,
Land323,
Land331,
Land332,
Land333,
Land611,
Land612,
Land613,
Land621,
Land622,
Land623,
Land631,
Land632,
Land633,
LittleBoss,
Whale,
}

public enum Towers
{
Anchor,
Arrow,
Ball,
Bottle,
Buff,
Cuttle,
Fan,
FireBottle,
Fish,
Mushroom,
PStar,
Pin,
Plane,
Rocket,
Shit,
Snow,
Star,
Sun,
}
}

(4)然后是写一个可以直接通过音频名字查找路径,并动态加载的单例脚本,相当于资源加载类,其他的资源也可以用它来完成加载
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);
}
}

(5)然后是最重要的角色了,音频管理脚本
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;
}
}

//重写虚方法
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;
}

// 播放背景音乐,传进一个音频剪辑的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)
{
//根据查找路径加载对应的音频剪辑
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);
}

}

(6)实例应用
可以直接点出想要的音频剪辑


代码,脚本直接挂在到空物体上GameController
using UnityEngine;
using System.Collections;

public class GameController : MonoBehaviour
{

void Update ()
{
if (Input.GetKeyDown (KeyCode.B)) {
MusicMgr.Instance.PlayBg (MusicType.Main.BGMusic);
}
if (Input.GetKeyDown (KeyCode.E)) {
MusicMgr.Instance.PlayEffect (MusicType.Towers.Bottle);
}

————————————————
版权声明:本文为CSDN博主「GaoHeShun」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/GaoHeShun/article/details/66975254

posted @ 2019-11-14 16:26  自長安的李少俠  阅读(520)  评论(0编辑  收藏  举报