AudioManager

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;

public class AudioPlay_OnBegin
{
    public string audioName;

    public AudioPlay_OnBegin(string audioName)
    {
        this.audioName = audioName;
    }
}

public class AudioPlay_OnComplete
{
    public string audioName;

    public AudioPlay_OnComplete(string audioName)
    {
        this.audioName = audioName;
    }
}

public class AudioManager : MonoBehaviour
{
    public static AudioManager instance;
    //背景音只允许有一个
    AudioSource bgAudioSource;
    //人声允许有多个
    List<AudioSource> voiceAudioSources;
    List<Coroutine> voiceCoroutines;

    private void Awake()
    {
        instance = this;

        Component[] components = GetComponents<AudioSource>();
        if (components.Length > 0)
        {
            for (int i = 0; i < components.Length; i++)
            {
                Destroy(components[i]);
            }
        }

        bgAudioSource = gameObject.AddComponent<AudioSource>();
        voiceAudioSources = new List<AudioSource>();
        voiceCoroutines = new List<Coroutine>();
    }

    /// <summary>
    /// 停止播放背景音频
    /// </summary>
    public void StopBgAudio()
    {
        bgAudioSource.Stop();
    }

    /// <summary>
    /// 暂停播放背景音频
    /// </summary>
    public void PauseBgAudio()
    {
        bgAudioSource.Pause();
    }

    /// <summary>
    /// 继续播放背景音频,仅适用于Pause后的情况
    /// </summary>
    public void ContinuePlayBgAudio()
    {
        bgAudioSource.Play();
    }

    /// <summary>
    /// 播放背景音频
    /// </summary>
    /// <param name="filePath">音频全路径</param>
    /// <param name="loop">是否循环播放</param>
    /// <returns></returns>
    public AudioClip PlayBgAudio(string filePath, bool loop = true, float volume = 1)
    {
        AudioClip clip = null;
        StartCoroutine(LoadAudio(filePath, (audio) => {
            if (audio != null)
            {
                PlayVoice(audio);
                clip = audio;
            }
        }));
        return clip;
    }

    public void PlayBgAudio(AudioClip audioClip, bool loop = true, float volume = 1)
    {
        if (bgAudioSource.isPlaying)
        {
            bgAudioSource.Stop();
        }

        bgAudioSource.clip = audioClip;
        bgAudioSource.loop = loop;
        bgAudioSource.volume = volume;
        bgAudioSource.Play();
    }

    /// <summary>
    /// 是否正在播放Voice
    /// </summary>
    /// <param name="audioClipName">Voice名称</param>
    /// <returns></returns>
    public bool IsPlayingVoice(string audioClipName)
    {
        bool playing = false;
        for (int i = 0; i < voiceAudioSources.Count; i++)
        {
            if (voiceAudioSources[i].clip.name.Equals(audioClipName))
            {
                playing = true;
                break;
            }
        }

        return playing;
    }

    /// <summary>
    /// 停止所有的Voice播放
    /// </summary>
    public void StopAllVoiceAudio()
    {
        for (int i = 0; i < voiceAudioSources.Count; i++)
        {
            voiceAudioSources[i].Stop();
            StopCoroutine(voiceCoroutines[i]);
            Destroy(voiceAudioSources[i]);
        }

        voiceAudioSources.Clear();
        voiceCoroutines.Clear();
    }

    IEnumerator LoadAudio(string fileName, Action<AudioClip> loadAudioCompleteAct)
    {
        //获取.wav文件,并转成AudioClip
        UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(fileName, AudioType.WAV);
        //等待转换完成
        yield return www.SendWebRequest();
        //获取AudioClip
        AudioClip audioClip = DownloadHandlerAudioClip.GetContent(www);
        if (loadAudioCompleteAct != null) loadAudioCompleteAct.Invoke(audioClip);
    }

    /// <summary>
    /// 播放音频,仅限wav格式的音频
    /// </summary>
    /// <param name="filePath">wav音频全路径</param>
    public AudioClip PlayVoice(string filePath)
    {
        AudioClip clip = null;
        StartCoroutine(LoadAudio(filePath, (audio) => {
            if (audio != null)
            {
                PlayVoice(audio);
                clip = audio;
            }
        }));
        return clip;
    }

    public void PlayVoice(AudioClip audioClip)
    {
        AudioSource audioSource = gameObject.AddComponent<AudioSource>();
        voiceAudioSources.Add(audioSource);

        audioSource.clip = audioClip;
        audioSource.Play();
        TypeEventSystem.Send(new AudioPlay_OnBegin(audioClip.name));
        voiceCoroutines.Add(StartCoroutine(WaitPlayAudioComplete(audioSource, audioClip)));
    }

    IEnumerator WaitPlayAudioComplete(AudioSource audioSource, AudioClip audioClip, bool isVoice = true)
    {
        yield return new WaitForSeconds(audioClip.length);
        if (isVoice)
        {
            int index = voiceAudioSources.IndexOf(audioSource);
            voiceAudioSources.Remove(audioSource);
            voiceCoroutines.RemoveAt(index);
            Destroy(audioSource);
        }
        TypeEventSystem.Send(new AudioPlay_OnComplete(audioClip.name));
    }
}