zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Hadoop与分布式开发
    Hadoop体系结构
    MapReduce基本流程与设计思想初步
    hadoop集群启动时DataNode节点启动失败
    初识Hadoop
    国家标准免费下载网站大全
    Effective C++ 之 Item 3:尽可能使用 const
    Effective C++ 之 Item 2:尽量以 const, enum, inline 替换 #define
    Effective C++ 之 Item 1: 视C++为一个语言联邦
    Effective C++ 之 0 导读(Introduction)
  • 原文地址:https://www.cnblogs.com/LiTZen/p/11858196.html
Copyright © 2011-2022 走看看