欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自建快速集成AudioPlayer插件,本地音频播放小工具,能满足大部分日常接触到的声音播放功能

程序员文章站 2022-05-31 17:31:27
...

        之前做过的大大小小的项目,都会涉及到声音资源的播放,虽然播放声音片段技术含量不高,几步就能搞定,但如果每次建项目都需要写个声音播放类也比较麻烦,不同的项目可能也有不同的功能要求,有的只需要播放就行,再就是每次写的若有针对性,以后回看代码会降低效率,所以就把我以前所使用到的功能集合到一起,把声音播放功能做成一个预制体,即方便使用,也能统一方法。主要能实现声音的播放,暂停,停止,缓存,音量调节,循环,是否覆盖,播放完成回调等功能,后面若接触到新的需要还会继续添加迭代。

制作思路也比较简单,就是将音频播放分为不同的类型,如背景音,特效音,人物语言等等,每个类型的音频用一个AudioSourece播放,然后在播放的时候需要指出播放那个类型的音频,以及播放音频的文件名。

使用方式如下:

1,新建空组件GameObject(不限定),添加AudioPlayer脚本

自建快速集成AudioPlayer插件,本地音频播放小工具,能满足大部分日常接触到的声音播放功能

2,约定一个音效类型(代码中会根据类型播放),如:bg,然后指定他的资源路径,最后点击“添加播放器”

自建快速集成AudioPlayer插件,本地音频播放小工具,能满足大部分日常接触到的声音播放功能

点击后,GameObject下会出现一个子物体,名字是AS(audiosource)+你约定的音频类型名称,然后会自动挂上了AudioSource组件,挂上了本组件的配置信息脚本

自建快速集成AudioPlayer插件,本地音频播放小工具,能满足大部分日常接触到的声音播放功能

3,使用方式如下:前两个参数是必填项,一个是播放声音的片段类型,他决定了在哪个AudioSource上面播放,第二个是声音片段的文件名

  自建快速集成AudioPlayer插件,本地音频播放小工具,能满足大部分日常接触到的声音播放功能

播放完成监听(每个使用类设置一个就行,不需要针对每个声音片段设置):需要将播放方法的是否监听设置为ture,然后该声音片段播发完成后result就能返回该片段名称

自建快速集成AudioPlayer插件,本地音频播放小工具,能满足大部分日常接触到的声音播放功能

下面是AudioPlayer的源码,调用AudioPlay()方法进行播放,可以设置是否缓存,音量,是否循环,是否覆盖(若已经在播放该片段的情况下),播放完成后是否需要反馈。后面可调用方法分别是停止,暂停,继续播放,传入相应的声音类型即可。

public class AudioPlayer : MonoBehaviour
    {
        private static AudioPlayer _audioPlayer;
        private List<AudioItem> audioClasses;
        //public List<AudioOverListener> audioOverListeners;
        //public delegate void AudioOverListener(string name);
        public Action<string> AudioOverAction;

        private void Awake()
        {
            _audioPlayer = this.GetComponent<AudioPlayer>();
            audioClasses = new List<AudioItem>();
            foreach (Transform child in transform)
            {
                AudioItem audioItem = child.GetComponent<AudioItem>();
                audioClasses.Add(new AudioItem(audioItem.ResourceType, audioItem.ResourcePath, audioItem.ItemAudioSource));
            }
        }
        public static AudioPlayer GetInstance()
        {
            return _audioPlayer;
        }
        /// <summary>
        /// 播放声音片段方法
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="audioName">片段名称</param>
        /// <param name="cache">是否缓存</param>
        /// <param name="volume">音量</param>
        /// <param name="isLoop">是否循环</param>
        /// <param name="isCover">是否覆盖</param>
        /// <param name="isOverListener">是否需要播放完成回调监听</param>
        public void AudioPlay(string type, string audioName, bool cache = false, bool isLoop = false, bool isCover = true, bool isOverListener = false, float volume = 1)
        {
            foreach (AudioItem child in audioClasses)
            {
                if (child.ResourceType.Equals(type))
                {
                    AudioClip ac;
                    if (!child.AudioDic.TryGetValue(audioName, out ac))
                    {
                        ac = Resources.Load<AudioClip>(child.ResourcePath + "/" + audioName);
                        if (cache)
                        {
                            child.AudioDic.Add(audioName, ac);
                        }
                    }
                    else
                    {
                        ac = child.AudioDic[audioName];
                    }
                    if (child.ItemAudioSource != null)
                    {
                        if (!isCover && child.ItemAudioSource.isPlaying)
                        {
                            if (child.ItemAudioSource.clip.name.Equals(audioName)) return;
                        }
                        child.ItemAudioSource.clip = ac;
                        child.ItemAudioSource.loop = isLoop;
                        child.ItemAudioSource.volume = volume;
                        child.ItemAudioSource.Play();
                        if (isOverListener)
                            StartCoroutine(PlayBack(ac.name, ac.length));
                    }
                    break;
                }
            }
        }

        private IEnumerator PlayBack(string name, float length)
        {
            yield return new WaitForSeconds(length);
            AudioOverAction(name);
        }
        /// <summary>
        /// 结束
        /// </summary>
        /// <param name="type">音频类型</param>
        public void Stop(string type)
        {
            foreach (AudioItem child in audioClasses)
            {
                if (child.ResourceType.Equals(type))
                {
                    if (child.ItemAudioSource != null && child.ItemAudioSource.isPlaying)
                    {
                        child.ItemAudioSource.Stop();
                    }
                }
            }
        }
        /// <summary>
        /// 暂停
        /// </summary>
        /// <param name="type">音频类型</param>
        public void Pause(string type)
        {
            foreach (AudioItem child in audioClasses)
            {
                if (child.ResourceType.Equals(type))
                {
                    if (child.ItemAudioSource != null && child.ItemAudioSource.isPlaying)
                    {
                        child.ItemAudioSource.Pause();
                    }
                }
            }
        }
        /// <summary>
        /// 继续播放
        /// </summary>
        /// <param name="type">音频类型</param>
        public void Restart(string type)
        {
            foreach (AudioItem child in audioClasses)
            {
                if (child.ResourceType.Equals(type))
                {
                    if (child.ItemAudioSource != null)
                    {
                        child.ItemAudioSource.Play();
                        Debug.Log("继续播放");
                    }
                }
            }
        }
    }

下面是音频播放器Item属性,用来存放每个类型的播放器配置

/// <summary>
    /// 音频播放器Item属性
    /// </summary>
    [Serializable]
    public class AudioItem : MonoBehaviour
    {

        [SerializeField]
        private string resourceType;
        [SerializeField]
        private string resourcePath;
        [SerializeField]
        private AudioSource audioSource;
        [HideInInspector]
        private Dictionary<string, AudioClip> audioDic;
        private Action<string> audioOverAction;

        #region
        public AudioItem(string type, string path, AudioSource audios)
        {
            ResourceType = type;
            ResourcePath = path;
            ItemAudioSource = audios;
            audioDic = new Dictionary<string, AudioClip>();
        }


        public string ResourceType
        {
            get
            {
                return resourceType;
            }

            set
            {
                resourceType = value;
            }
        }

        public string ResourcePath
        {
            get
            {
                return resourcePath;
            }

            set
            {
                resourcePath = value;
            }
        }

        public AudioSource ItemAudioSource
        {
            get
            {
                return audioSource;
            }

            set
            {
                audioSource = value;
            }
        }

        public Dictionary<string, AudioClip> AudioDic
        {
            get
            {
                return audioDic;
            }

            set
            {
                audioDic = value;
            }
        }
        #endregion
    }

最后是音频播放器item生成工具,就是前面配置类型和路径然后点击“添加播放器”按钮生成子播放器的工具类

 /// <summary>
    /// 音频播放器item生成工具
    /// </summary>
    [CustomEditor(typeof(AudioPlayer))]
    public class AddAudioPalyerItem : Editor
    {

        private static AddAudioPalyerItem _addAudioPalyerItem;
        public AddAudioPalyerItem GetInstance()
        {
            if (_addAudioPalyerItem == null)
            {
                _addAudioPalyerItem = new AddAudioPalyerItem();
            }
            return _addAudioPalyerItem;
        }

        private string typeText;
        private string pathText;
        /// <summary>
        /// <param name="音效类型">播放音效时需按指定类型播放,如bg,player等</param>
        /// <param name="资源路径">Resources下声音片段的具体路径文件夹,同个类型的音效放入同个资源路径</param>
        /// </summary>
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            typeText = EditorGUILayout.TextField("音效类型:", typeText);
            pathText = EditorGUILayout.TextField("资源路径:", pathText);

            if (isValue(typeText) & isValue(pathText))
            {
                if (GUILayout.Button("添加播放器"))
                {
                    GameObject go = new GameObject();
                    go.name = "AS_" + typeText;
                    go.AddComponent<AudioSource>().playOnAwake = false;
                    go.transform.parent = Selection.activeTransform;
                    go.AddComponent<AudioItem>();
                    go.GetComponent<AudioItem>().ResourcePath = pathText;
                    go.GetComponent<AudioItem>().ResourceType = typeText;
                    go.GetComponent<AudioItem>().ItemAudioSource = go.GetComponent<AudioSource>();
                    typeText = "";
                    pathText = "";
                }
            }
        }

        private bool isValue(string str)
        {
            if (str == null | str.Equals(""))
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }

最后给出导出的unitypackage工具包百度网盘地址,是用unity2017.3.1导出的

https://pan.baidu.com/s/18EWw2YgrkjaIv8j2i7x8qw