using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Audio; namespace AlicizaX.Audio.Runtime { /// /// 音频轨道(类别)。 /// [Serializable] public class AudioCategory { [SerializeField] private AudioMixer audioMixer = null; public List AudioAgents; private readonly AudioMixerGroup _audioMixerGroup; private AudioGroupConfig _audioGroupConfig; private int _maxChannel; private bool _bEnable = true; /// /// 音频混响器。 /// public AudioMixer AudioMixer => audioMixer; /// /// 音频混响器组。 /// public AudioMixerGroup AudioMixerGroup => _audioMixerGroup; /// /// 音频组配置。 /// public AudioGroupConfig AudioGroupConfig => _audioGroupConfig; /// /// 实例化根节点。 /// public Transform InstanceRoot { private set; get; } /// /// 音频轨道是否启用。 /// public bool Enable { get => _bEnable; set { if (_bEnable != value) { _bEnable = value; if (!_bEnable) { foreach (var audioAgent in AudioAgents) { if (audioAgent != null) { audioAgent.Stop(); } } } } } } /// /// 音频轨道构造函数。 /// /// 最大Channel。 /// 音频混响器。 /// 音频轨道组配置。 public AudioCategory(int maxChannel, AudioMixer audioMixer, AudioGroupConfig audioGroupConfig) { var audioModule = ModuleSystem.GetModule(); this.audioMixer = audioMixer; _maxChannel = maxChannel; _audioGroupConfig = audioGroupConfig; AudioMixerGroup[] audioMixerGroups = audioMixer.FindMatchingGroups(Utility.Text.Format("Master/{0}", audioGroupConfig.AudioType.ToString())); if (audioMixerGroups.Length > 0) { _audioMixerGroup = audioMixerGroups[0]; } else { _audioMixerGroup = audioMixer.FindMatchingGroups("Master")[0]; } AudioAgents = new List(32); InstanceRoot = new GameObject(Utility.Text.Format("Audio Category - {0}", _audioMixerGroup.name)).transform; InstanceRoot.SetParent(audioModule.InstanceRoot); for (int index = 0; index < _maxChannel; index++) { AudioAgent audioAgent = new AudioAgent(); audioAgent.Init(this, index); AudioAgents.Add(audioAgent); } } /// /// 增加音频。 /// /// public void AddAudio(int num) { _maxChannel += num; for (int i = 0; i < num; i++) { AudioAgents.Add(null); } } public AudioAgent Play(AudioClip clip) { if (!_bEnable) { return null; } int freeChannel = -1; float duration = -1; for (int i = 0; i < AudioAgents.Count; i++) { if (AudioAgents[i].IsFree) { freeChannel = i; break; } else if (AudioAgents[i].Duration > duration) { duration = AudioAgents[i].Duration; freeChannel = i; } } if (freeChannel >= 0) { if (AudioAgents[freeChannel] == null) { AudioAgents[freeChannel] = AudioAgent.Create(clip, this); } else { AudioAgents[freeChannel].SetAudioClip(clip); } return AudioAgents[freeChannel]; } else { Log.Error($"Here is no channel to play audio clip"); return null; } } /// /// 播放音频。 /// /// /// /// /// public AudioAgent Play(string path, bool bAsync, bool bInPool = false) { if (!_bEnable) { return null; } int freeChannel = -1; float duration = -1; for (int i = 0; i < AudioAgents.Count; i++) { if (AudioAgents[i].AudioData?.AssetHandle == null || AudioAgents[i].IsFree) { freeChannel = i; break; } else if (AudioAgents[i].Duration > duration) { duration = AudioAgents[i].Duration; freeChannel = i; } } if (freeChannel >= 0) { if (AudioAgents[freeChannel] == null) { AudioAgents[freeChannel] = AudioAgent.Create(path, bAsync, this, bInPool); } else { AudioAgents[freeChannel].Load(path, bAsync, bInPool); } return AudioAgents[freeChannel]; } else { Log.Error($"Here is no channel to play audio {path}"); return null; } } /// /// 暂停音频。 /// /// 是否渐出 public void Stop(bool fadeout) { for (int i = 0; i < AudioAgents.Count; ++i) { if (AudioAgents[i] != null) { AudioAgents[i].Stop(fadeout); } } } /// /// 音频轨道轮询。 /// /// 逻辑流逝时间,以秒为单位。 public void Update(float elapseSeconds) { for (int i = 0; i < AudioAgents.Count; ++i) { if (AudioAgents[i] != null) { AudioAgents[i].Update(elapseSeconds); } } } } }