Unity 音频管理框架

AudioPlayManager

使用AudioPlayManager管理AuidoSourceManager和AudioClipManager。

提供一次性播放(播放完毕就结束)。

提供循环播放,返回SingleAudioClip,使用返回的SingleAudioClip停止播放。

using UnityEngine;

public class AudioPlayManager : MonoBehaviour
{
    public static AudioPlayManager instance;

    private AudioSourceManager audioSourceManager;
    private AudioClipManager audioClipManager;
    
    private void Start()
    {
        instance = this;
        audioSourceManager = new AudioSourceManager(gameObject);
        audioClipManager = new AudioClipManager();
    }

    private void Update()
    {
        audioSourceManager.ReleaseFreeAudioSource();
    }

    /// <summary>
    /// 播放音频(一次)
    /// </summary>
    /// <param name="audioClipName"></param>
    public void PlayOnceAudio(string audioClipName)
    {
        AudioSource tempAudioSource = audioSourceManager.FindFreeAudioSource();
        SingleAudioClip tempSingleAudioClip = audioClipManager.FindSingleAudioClip(audioClipName);
        
        tempSingleAudioClip.Initialize(tempAudioSource);
        
        tempSingleAudioClip.PlayAudio();
    }

    /// <summary>
    /// 播放音乐(需要调用StopPlay关闭)
    /// </summary>
    /// <param name="audioClipName"></param>
    public SingleAudioClip PlayAudio(string audioClipName)
    {
        AudioSource tempAudioSource = audioSourceManager.FindFreeAudioSource();
        SingleAudioClip tempSingleAudioClip = audioClipManager.FindSingleAudioClip(audioClipName);
        
        tempSingleAudioClip.Initialize(tempAudioSource);
        
        tempSingleAudioClip.PlayAudio();

        return tempSingleAudioClip;
    }
}

AudioSourceManager

管理所有AudioSource组件,控制AudioSource组件的数量。

分配用于播放的AudioSource,释放多余的AudioSource。

using System.Collections.Generic;
using UnityEngine;

public class AudioSourceManager
{
    private List<AudioSource> _audioSources;

    private GameObject playLocation;

    public AudioSourceManager(GameObject playLocation)
    {
        this.playLocation = playLocation;
        Initial();
    }
    
    /// <summary>
    /// 初始化
    /// </summary>
    private void Initial()
    {
        _audioSources = new List<AudioSource>();
        
        // 初始化三个AudioSource
        for (int i = 0; i < 3; i++)
        {
            _audioSources.Add(playLocation.AddComponent<AudioSource>());
        }
    }

    /// <summary>
    /// 找到空闲的AudioSource
    /// </summary>
    /// <returns></returns>
    public AudioSource FindFreeAudioSource()
    {
        for (int i = 0; i < _audioSources.Count; i++)
        {
            if (!_audioSources[i].isPlaying)
            {
                return _audioSources[i];
            }
        }
        
        // 没有空闲的AudioSource,创建新的AudioSource
        AudioSource tempSource = playLocation.AddComponent<AudioSource>();
        
        // 添加
        _audioSources.Add(tempSource);

        return tempSource;
    }

    /// <summary>
    /// 释放多余的AudioSource【大于3个】
    /// </summary>
    public void ReleaseFreeAudioSource()
    {
        int freeCount = 0;

        List<AudioSource> tempSources = new List<AudioSource>();
        
        // 记录有多少AudioSource没有播放
        for (int i = 0; i < _audioSources.Count; i++)
        {
            if (!_audioSources[i].isPlaying)
            {
                // 如果空闲AudioSource大于3个
                if (++freeCount>3)
                {
                    tempSources.Add(_audioSources[i]);
                }
            }
        }

        // 释放多余的AudioSource
        for (int i = 0; i < tempSources.Count; i++)
        {
            _audioSources.Remove(tempSources[i]);
            GameObject.Destroy(tempSources[i]);
        }
        
        // 释放临时List<>
        tempSources.Clear();
        tempSources = null;
    }
}

AudioClipManager

管理所有的音频文件。

初始化时从txt文档中获取所有音频assetbundle名称,再从assetbundle中获取所有的音频。

提供通过音频名称获取包装成的SingleAudioClip

using System.IO;
using UnityEngine;

public class AudioClipManager
{
    private string[] audioClipNames;

    private SingleAudioClip[] singleAudioClips;

    public AudioClipManager()
    {
        Initial();
    }

    private void Initial()
    {
        ReadAudioClipName();
        LoadAudioClip();
    }

    /// <summary>
    /// 从txt文件中读取AudioClipName
    /// </summary>
    private void ReadAudioClipName()
    {
        FileStream fs = new FileStream(Application.streamingAssetsPath+"/AudioClips.txt", FileMode.Open, FileAccess.Read, FileShare.None);
        StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default);
        if (sr == null) 
            return;
        
        // 读取第一行
        string clips = sr.ReadLine();

        int clipCount = -1;

        if (int.TryParse(clips, out clipCount))
        {
            // 初始化audioClipNames
            audioClipNames = new string[clipCount];
            
            for (int i = 0; i < clipCount; i++)
            {
                audioClipNames[i] = sr.ReadLine().Split('|')[0];
            }
        }
        
        sr.Close();
    }

    /// <summary>
    /// 加载AudioClip
    /// </summary>
    private void LoadAudioClip()
    {
        // 初始化
        singleAudioClips = new SingleAudioClip[audioClipNames.Length];
        
        for (int i = 0; i < audioClipNames.Length; i++)
        {
            // 加载
            // AudioClip tempClip = Resources.Load<AudioClip>(audioClipNames[i]);
            AudioClip tempClip = ResourceAndDataManager.Instance.ObtainAudioClip(audioClipNames[i]);
            
            // 存储
            singleAudioClips[i] = new SingleAudioClip(tempClip);
        }
    }

    /// <summary>
    /// 通过AudioClipName获取SingleAudioClip
    /// </summary>
    /// <param name="audioClipName"></param>
    /// <returns></returns>
    public SingleAudioClip FindSingleAudioClip(string audioClipName)
    {
        for (int i = 0; i < audioClipNames.Length; i++)
        {
            // 如果找到
            if (audioClipNames[i].Equals(audioClipName))
            {
                return singleAudioClips[i];
            }
        }
        
        // 没有找到
        return null;
    }
}

SingleAudioClip

包装AudioSource和AudioClip,提供播放和停止播放方法。

using UnityEngine;

public class SingleAudioClip
{
    private AudioClip audioClip;
    private AudioSource audioSource;

    public SingleAudioClip(AudioClip audioClip)
    {
        this.audioClip = audioClip;
    }

    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="audioSource"></param>
    public void Initialize(AudioSource audioSource)
    {
        audioSource.clip = audioClip;
        this.audioSource = audioSource;
    }

    /// <summary>
    /// 播放AudioClip
    /// </summary>
    public void PlayAudio()
    {
        audioSource.Play();
    }

    /// <summary>
    /// 关闭AudioClip
    /// </summary>
    public void StopAudio()
    {
        audioSource.Stop();
    }
}

猜你喜欢

转载自blog.csdn.net/heaventianjianke/article/details/127160941