using System; using System.Collections.Generic; using System.Linq; //using CriWare; using Cysharp.Threading.Tasks; using Framework; using PhxhSDK; using UnityEngine; using UnityEngine.Audio; using Constants = Framework.Constants; using Object = UnityEngine.Object; using EPlayType = AudioCriManager.EPlayType; public class AudioUnityManager: Singlenton, IStart, IInitable, IUpdatable, IAudioPlay { public GameObject initGameObject; public GameObject AudioRoot; public GameObject CriAtomRoot; //public CriAtom CriAtom; public ClipType curClipType; private AudioInst _bgmAudioCri; // public CriAtomListener Listener; // private Dictionary _cacheCueInfoArrays = new(); /// /// 对象池数量限制 /// public int MusicPoolLimit = 1; public int SoundPoolLimit = 100; public int SpeakPoolLimit = 1; // public enum EPlayType // { // Music, // Sound, // Speak // } private GameObject _criError; /// /// 播放音频对象池 /// private Dictionary _soundAudioDic; private Dictionary _soundAudioLoopDic; private Dictionary _musicAudioDic; private Dictionary _musicAudioLoopDic; private Dictionary _allAudioDic; private List _soundAudioObj; private List _soundAudioLoopObj; private List _musicAudioObj; private List _musicAudioLoopObj; public enum PlayType { Music, Sound, Speak } private Dictionary> _playingLDic; private List _soundAudioQue; private Dictionary _storyAudioDic; private const int SOUND_MAX_NUM = 20; private const int MUSIC_MAX_NUM = 2; public AudioListener GlobalListener; //全局监听 private bool _isFollowCamera = false; //是否跟随相机 public AudioMixer masterMixer; #region Property private float _vol = 1f; public float GlobalSoundsVolume { get => AudioUnity.GlobalSoundVolume; set => AudioUnity.GlobalSoundVolume = value; } public float GlobalSpeakVolume{ get => AudioUnity.GlobalSpeakVolume; set => AudioUnity.GlobalSpeakVolume = value; } public float GlobalMusicVolume { get => AudioUnity.GlobalMusicVolume; set => AudioUnity.GlobalMusicVolume = value; } public float GlobalVolume { get => AudioUnity.GlobalVolume; set => AudioUnity.GlobalVolume = value; } public bool GlobalIsOpenSpeak; public AudioInst BgmAudioCri { get { return _bgmAudioCri; } set { _bgmAudioCri = value; } } //public CriAtomExOutputAnalyzer analyzer=null; public bool IsAnalyzer = false; #endregion #region Analyze //在播放之前注册 // public CriAtomExOutputAnalyzer RegisterAnalyzer()//CriAtomExOutputAnalyzer s // { // IsAnalyzer = true; // if (analyzer == null) // { // analyzer = new(NewAnalyzerConfig()); // } // return analyzer; // //analyzer = s; // } // // public void UnregisterAnalyzer()//CriAtomExOutputAnalyzer s // { // //s.DetachExPlayer(); // IsAnalyzer = false; // //analyzer = null; // } // // /// // /// 获取音频输出分析器配置 // /// // /// // private CriAtomExOutputAnalyzer.Config NewAnalyzerConfig() // { // CriAtomExOutputAnalyzer.Config config = new() // { // enableSpectrumAnalyzer = true, // 开启频谱分析 // numSpectrumAnalyzerBands = 16, // 频谱分析数量SPECTRUM_SAMPLES_NUMBER // }; // // return config; // } #endregion #region Framework public void Start() { if (!AudioRoot) { curClipType = ClipType.AudioClip; AudioRoot = new GameObject(); AudioRoot.name = "Audio(Singleton)"; Object.DontDestroyOnLoad(AudioRoot); GlobalListener = AudioRoot.AddComponent(); _InitListenerPos(); InitMixer(); // if (curClipType == ClipType.CriwareClip) // { // _criError = new GameObject(); // _criError.name = "CriwareError"; // _criError.AddComponent(); // Object.DontDestroyOnLoad(_criError); // } // var initialize = GameObject.Find("CriWareLibraryInitializer"); // Object.DontDestroyOnLoad(initialize); // CriAtomRoot = GameObject.Find("CriAtom"); // CriAtom = CriAtomRoot.GetComponent(); //Object.DontDestroyOnLoad(CriAtomRoot); } // CriAtomRoot = new GameObject() // { // name = "CriAtom" // }; // CriAtom = CriAtomRoot.AddComponent(); // CriAtom.AddCueSheet() // for (int i = 0; i < SOUND_MAX_NUM; i++) // { // var go = new GameObject // { // name = "Sound" + (i+1) // }; // go.transform.SetParent(AudioRoot.transform); // } // // for (int i = 0; i < MUSIC_MAX_NUM; i++) // { // var go = new GameObject // { // name = "Music" + (i+1) // }; // go.transform.SetParent(AudioRoot.transform); // } } public void Init() { _soundAudioDic = new Dictionary(); _soundAudioLoopDic = new Dictionary(); _musicAudioDic = new Dictionary(); _musicAudioLoopDic = new Dictionary(); _allAudioDic = new Dictionary(); _soundAudioLoopObj = new(); _musicAudioLoopObj = new(); _soundAudioObj = new(); _musicAudioObj = new(); _playingLDic = new (); _playingLDic.Add(PlayType.Music, new List()); _playingLDic.Add(PlayType.Sound, new List()); _playingLDic.Add(PlayType.Speak, new List()); _storyAudioDic = new(); EventManager.Instance.Register(EventManager.EventName.Audio_ErrorAudioPlay, _OnErrorAudioPlay); } public void Release() { EventManager.Instance.Unregister(EventManager.EventName.Audio_ErrorAudioPlay, _OnErrorAudioPlay); } public void Update(float dt) { _SetListenerPos(); foreach (var kv in _musicAudioDic) { var audio = kv.Value; if (!audio.IsStopped) { audio.Update(dt); } } foreach (var kv in _musicAudioLoopDic) { var audio = kv.Value; if (!audio.IsStopped) { audio.Update(dt); } } foreach (var kv in _soundAudioDic) { var audio = kv.Value; if (!audio.IsStopped) { audio.Update(dt); } } foreach (var kv in _soundAudioLoopDic) { var audio = kv.Value; if (!audio.IsStopped) { audio.Update(dt); } } foreach (var kv in _storyAudioDic) { var audio = kv.Value; if (!audio.IsStopped) { audio.Update(dt); } } } #endregion #region LoadAsset private async void InitMixer() { masterMixer = await AssetManager.Instance.LoadAssetAsync("Assets/Audio/AudioMixers/MasterMixer.mixer"); masterMixer.SetFloat("MasterCompressorThreshold", -10f); } private string GetFullPath(string key, bool isI18N = false) { var cfg = TableManager.Instance.Tables.AudioSourceConfig.GetOrDefault(key); if (cfg == null) { DebugUtil.LogError($"音频Key:{key}找不到!"); return ""; } if (isI18N) { var path = cfg.Path; if (path.Contains(LanguageManager.I18N)) { var eLanguage = LanguageManager.Instance.GetCurrentLanguage(); var replacePath = LanguageManager.PathDic[eLanguage]; path = path.Replace(LanguageManager.I18N, replacePath); } return path; } return cfg.Path; } //优化SplitGC private string _GetCriPath(string name) { var firstChar = name[0]; if (!string.IsNullOrEmpty(name)) { if (firstChar == 'b') { return "CueSheet_bgm"; } if (firstChar == 'V') { return "CueSheet_Voice"; } if (firstChar == 'S') { return "CueSheet_Sound"; } if (firstChar == 'e') { return "CueSheet_ev"; } if (firstChar == 'u') { return "CueSheet_ui"; } } return ""; } private string _GetAcbPath(string name) { var path = _GetCriPath(name); if (string.IsNullOrEmpty(path)) { DebugUtil.LogError($"获取不到对应的ACB文件,key: {name}"); return ""; } return path + ".acb"; } private string _GetAwbPath(string name) { var path = _GetCriPath(name); if (string.IsNullOrEmpty(path)) { DebugUtil.LogError($"获取不到对应的AWB文件,key: {name}"); return ""; } return path + ".awb"; } private string _GetAcfPath(string name) { var path = _GetCriPath(name); if (path == null) { DebugUtil.LogError($"获取不到对应的ACF文件,key: {name}"); return ""; } return path + ".acf"; } #endregion #region AudioObj /// /// 获取可用的Audio /// /// /// private AudioInst _GetUsableAudio(AudioBase.AudioType audioType, bool isLoop, bool isSpeak = false) { try { var limit = _CheckIsAudioLimited(audioType, isSpeak); if (limit) { return _GetOldAudio(audioType, isLoop, isSpeak); } var freeAudio = _GetFreeAudio(audioType, isLoop); return freeAudio ?? _CreateNewAudio(audioType, isLoop); } catch (Exception e) { DebugUtil.LogError($"AudioManger, GetUsableAudio Fail.{e}"); } return null; } private AudioInst _GetOldAudio(AudioBase.AudioType audioType, bool isLoop, bool isSpeak) { var playingList = _playingLDic[GetPlayType(audioType, isSpeak)]; if (playingList.Count > 0) { var audio = GetAudioByID(playingList[0]); return audio; } return _CreateNewAudio(audioType, isLoop); } private int _GetLimit(AudioBase.AudioType audioType, bool isSpeak) { if (isSpeak) { return SpeakPoolLimit; } if (audioType == AudioBase.AudioType.Music) { return MusicPoolLimit; } if (audioType == AudioBase.AudioType.Sound) { return SoundPoolLimit; } return -1; } private PlayType GetPlayType(AudioBase.AudioType audioType, bool isSpeak) { if (isSpeak) return PlayType.Speak; if (audioType == AudioBase.AudioType.Music) return PlayType.Music; return PlayType.Sound; } private bool _CheckIsAudioLimited(AudioBase.AudioType audioType, bool isSpeak) { var limit = _GetLimit(audioType, isSpeak); var playingList = _playingLDic[GetPlayType(audioType, isSpeak)]; if (playingList.Count >= limit) { return true; } return false; } private Dictionary _GetAudioDic(AudioBase.AudioType audioType, bool isLoop) { switch (audioType) { case AudioBase.AudioType.Music: return isLoop? _musicAudioLoopDic : _musicAudioDic; case AudioBase.AudioType.Sound: return isLoop? _soundAudioLoopDic : _soundAudioDic; default: { DebugUtil.LogError("获取AudioDic出错!!!传入AudioType有误!"); return null; } } } private AudioInst _GetFreeAudio(AudioBase.AudioType audioType, bool isLoop) { var dic = _GetAudioDic(audioType, isLoop); if (dic != null) { foreach (var kv in dic) { var audio = kv.Value; if (audio.IsStopped) { return audio; } } } return null; } private AudioInst _CreateStoryAudio(GameObject posGo = null, AudioBase.AudioType audioType = AudioBase.AudioType.Sound) { var rootGo = new GameObject() { name = "AudioStory" }; rootGo.transform.SetParent(AudioRoot.transform); var audio = new AudioInst(audioType, rootGo, null); rootGo.name += audio.audioID; _storyAudioDic.TryAdd(audio.audioID, audio); _allAudioDic.Add(audio.audioID, audio); return audio; } private AudioInst _CreateNewAudio(AudioBase.AudioType audioType, bool isLoop) { var rootGo = new GameObject() { name = "Audio" }; rootGo.transform.SetParent(AudioRoot.transform); var audio = new AudioInst(audioType, rootGo, null); if (audioType == AudioBase.AudioType.Music) { rootGo.name = "music"; rootGo.name += audio.audioID; if (isLoop) { rootGo.name += "Loop"; _musicAudioLoopDic.TryAdd(audio.audioID, audio); _musicAudioLoopObj.Add(rootGo); } else { _musicAudioDic.TryAdd(audio.audioID, audio); _musicAudioObj.Add(rootGo); } // if (IsAnalyzer) // { // rootGo.GetComponent().AttachToAnalyzer(analyzer); // } } if (audioType == AudioBase.AudioType.Sound) { rootGo.name = "Sound"; rootGo.name += audio.audioID; if (isLoop) { rootGo.name += "Loop"; _soundAudioLoopDic.TryAdd(audio.audioID, audio); _soundAudioLoopObj.Add(rootGo); } else { _soundAudioDic.TryAdd(audio.audioID, audio); _soundAudioObj.Add(rootGo); } } _allAudioDic.Add(audio.audioID, audio); return audio; } #endregion #region Play /// /// 调用接口,传obj /// /// /// /// /// private int _PlayAudio(string key, AudioCriManager.EPlayType type, GameObject posObj = null, bool isLoop = false, bool isFade = false, float fadeTime = 0f) { switch (type) { case AudioCriManager.EPlayType.Sound: if (AudioUnity.GlobalVolume <= 0 || AudioUnity.GlobalSoundVolume <= 0) { return -1; } break; case AudioCriManager.EPlayType.Speak: if (AudioUnity.GlobalVolume <= 0 || AudioUnity.GlobalSpeakVolume <= 0) { return -1; } break; default: break; } if (string.IsNullOrEmpty(key)) { return -1; } //策略2 超过限制不播 // var audioType = AudioBase.AudioType.Music; // bool isSpeak = false; // if (type == EPlayType.Sound) // { // audioType = AudioBase.AudioType.Sound; // } // if (type == EPlayType.Speak) // { // audioType = AudioBase.AudioType.Sound; // isSpeak = true; // } // if (_CheckIsAudioLimited(audioType, isSpeak)) // { // return -1; // } string path = _GetCriPath(key); switch (type) { case AudioCriManager.EPlayType.Music: { return _PlayMusic(key, posObj, isLoop, isFade, fadeTime); } case AudioCriManager.EPlayType.Sound: { return _PlaySound(key, posObj, isLoop, isFade, fadeTime); } case AudioCriManager.EPlayType.Speak: { return _PlaySpeakSound(key, posObj, isFade, fadeTime); } default: break; } return -1; } /// /// 调用接口,传位置 /// /// /// /// /// private int _PlayAudio(string key, AudioCriManager.EPlayType type, Vector3 pos, bool loop = false, bool isFade = false, float fadeTime = 0f) { //策略2 超过限制不播 // var audioType = AudioBase.AudioType.Music; // bool isSpeak = false; // if (type == EPlayType.Sound) // { // audioType = AudioBase.AudioType.Sound; // } // if (type == EPlayType.Speak) // { // audioType = AudioBase.AudioType.Sound; // isSpeak = true; // } // if (_CheckIsAudioLimited(audioType, isSpeak)) // { // return -1; // } switch (type) { case EPlayType.Sound: if (AudioUnity.GlobalVolume <= 0 || AudioUnity.GlobalSoundVolume <= 0) { return -1; } break; case EPlayType.Speak: if (AudioUnity.GlobalVolume <= 0 || AudioUnity.GlobalSpeakVolume <= 0) { return -1; } break; default: break; } string path = _GetCriPath(key); switch (type) { case EPlayType.Music: { return _PlayMusic(key, pos, loop, isFade, fadeTime); } case EPlayType.Sound: { return _PlaySound(key, pos, loop, isFade, fadeTime); } case EPlayType.Speak: { return _PlaySpeakSound(key, pos, isFade, fadeTime); } default: break; } return -1; } private int _PlayMusic(string key, GameObject posObj = null, bool isLoop = true, bool isFade = false, float fadeTime = 0f, float volume = 1f) { // if (GlobalMusicVolume < 0.01f) // { // return -1; // } var path = GetFullPath(key); if (!isFade) { // if (_bgmAudio != null) // { // _bgmAudio.Stop(); // } AudioInfo audioInfo = new AudioInfo() { persist = true, volume = 1, fadeInValue = 0.3f, fadeOutValue = 0.3f, }; var audio = _GetUsableAudio(AudioBase.AudioType.Music, isLoop); //错误打印,保护 if (audio == null) { DebugUtil.LogError($"AudioManager, PlayMusic, Cant GetUsableAudio key:{key}"); return -1; } audio.SetPosObj(posObj); audio.SetIsSpeak(false); audio.SetVolume(volume); audio.SetIsLoop(isLoop); // if (_bgmAudio != null && _bgmAudio != audio) // { // _bgmAudio.Stop(); // } //audio.Stop(); audio.Play(path); audio.SetIsLoop(isLoop); //_bgmAudio = audio; return audio.audioID; } else { AudioInfo audioInfo = new AudioInfo() { persist = true, volume = 1, fadeInValue = 0.3f, fadeOutValue = 0.3f, }; var audio = _GetUsableAudio(AudioBase.AudioType.Music, isLoop); audio.SetPosObj(posObj); audio.SetIsSpeak(false); // if (_bgmAudio != null && _bgmAudio != audio) // { // _bgmAudio.Stop(); // } //audio.SetIsFadeIn(true); audio.Stop(); audio.SetVolume(0); audio.PlayWithFade(path, fadeTime); audio.SetIsLoop(isLoop); //_bgmAudio = audio; return audio.audioID; } } private int _PlayMusic(string key, Vector3 pos, bool isLoop, bool isFade = false, float fadeTime = 0f, float volume = 1f) { // if (GlobalMusicVolume < 0.01f) // { // return -1; // } AudioInfo audioInfo = new AudioInfo() { persist = true, volume = 1, fadeInValue = 0.3f, fadeOutValue = 0.3f, }; var audio = _GetUsableAudio(AudioBase.AudioType.Music, isLoop); var path = GetFullPath(key); //错误打印,保护 if (audio == null) { DebugUtil.LogError($"AudioManager, PlayMusic By Pos, Cant GetUsableAudio key:{key}"); return -1; } audio.SetPos(pos); audio.SetIsSpeak(false); // if (_bgmAudio != null && _bgmAudio != audio) // { // _bgmAudio.Stop(); // } audio.SetIsLoop(true); audio.Stop(); if (isFade) { audio.SetVolume(0); audio.SetTargetVolume(volume); audio.PlayWithFade(path, fadeTime); } else { audio.Play(path); } //_bgmAudio = audio; audio.SetIsLoop(isLoop); return audio.audioID; } private int _PlaySound(string key, GameObject posObj = null, bool isLoop = false, bool isFade = false, float fadeTime = 0f, float volume = 1f) { if (GlobalSoundsVolume < 0.01f) { return -1; } AudioInfo audioInfo = new AudioInfo() { persist = true, volume = 1, fadeInValue = 0.3f, fadeOutValue = 0.3f, }; var audio = _GetUsableAudio(AudioBase.AudioType.Sound, isLoop); //错误打印,保护 if (audio == null) { DebugUtil.LogError($"AudioManager, PlaySound By Obj, Cant GetUsableAudio key:{key}"); return -1; } var path = GetFullPath(key); audio.Stop(); audio.SetPosObj(posObj); audio.SetIsSpeak(false); audio.SetIsLoop(isLoop); if (posObj) { audio.SetIs3D(true); } if (isFade) { audio.SetVolume(0); audio.PlayWithFade(path); } else { audio.SetVolume(volume); audio.Play(path); } audio.SetIsLoop(isLoop); return audio.audioID; } private int _PlaySound(string key, Vector3 pos, bool isLoop = false, bool isFade = false, float fadeTime = 0f, float volume = 1f) { if (GlobalSoundsVolume < 0.01f) { return -1; } AudioInfo audioInfo = new AudioInfo() { persist = true, volume = 1, fadeInValue = 0.3f, fadeOutValue = 0.3f, }; var audio = _GetUsableAudio(AudioBase.AudioType.Sound, isLoop); //错误打印,保护 if (audio == null) { DebugUtil.LogError($"AudioManager, PlaySound By Pos, Cant GetUsableAudio key:{key}"); return -1; } var path = GetFullPath(key); audio.Stop(); audio.SetPos(pos); audio.SetIsLoop(isLoop); audio.SetIsSpeak(false); audio.SetIs3D(true); if (isFade) { audio.SetVolume(0); audio.PlayWithFade(path, fadeTime); } else { audio.SetVolume(volume); audio.Play(path); } audio.SetIsLoop(isLoop); return audio.audioID; } private int _PlaySpeakSound(string key, GameObject posObj = null, bool isFade = false, float fadeTime = 0f, float volume = 1f) { if (GlobalSpeakVolume < 0.01f) { return -1; } AudioInfo audioInfo = new AudioInfo() { persist = true, volume = 1, fadeInValue = 0.3f, fadeOutValue = 0.3f, }; var audio = _GetUsableAudio(AudioBase.AudioType.Sound, false); //错误打印,保护 if (audio == null) { DebugUtil.LogError($"AudioManager, PlaySpeak By Obj, Cant GetUsableAudio key:{key}"); return -1; } var path = GetFullPath(key, true); audio.SetPosObj(posObj); audio.SetIsSpeak(true); if (isFade) { audio.SetVolume(0); audio.PlayWithFade(path, fadeTime); } else { audio.SetVolume(volume); audio.Play(path); } audio.SetIsLoop(false); return audio.audioID; } private int _PlaySpeakSound(string key, Vector3 pos, bool isFade = false, float fadeTime = 0f, float volume = 1f) { AudioInfo audioInfo = new AudioInfo() { persist = true, volume = 1, fadeInValue = 0.3f, fadeOutValue = 0.3f, }; var audio = _GetUsableAudio(AudioBase.AudioType.Sound, false); var path = GetFullPath(key, true); audio.SetPos(pos); audio.SetIsSpeak(true); if (isFade) { audio.SetVolume(0); audio.PlayWithFade(path, fadeTime); } else { audio.SetVolume(volume); audio.Play(path); } audio.SetIsLoop(false); return audio.audioID; } private void _PlayAudioByID(int id, string key, EPlayType type, GameObject posObj = null) { if (_soundAudioDic.TryGetValue(id, out var audio)) { } } private bool _CheckPath(string key) { var cfg = TableManager.Instance.Tables.AudioSourceConfig; if (cfg.GetOrDefault(key) != null) { return true; } return false; } #endregion #region API public int PlayAudio(string key, AudioCriManager.EPlayType type, GameObject posObj = null, bool loop = false, bool isFade = false, float fadeInTime = 4f) { // #if DEVELOPMENT_BUILD || DEBUG // DebugUtil.Log("播放音频:{0}, type:{1}", key, type); // #endif if (!_CheckPath(key)) { if (DebugUtil.LogEnable) { DebugUtil.LogG($"无法找到对应音频文件,key:{key}"); } return -1; } if (key == Constants.Sound.ERROR_UI || key == Constants.Sound.ERROR_UI_FIGHT) { EventManager.Instance.Send(EventManager.EventName.Audio_ErrorAudioPlay); } return _PlayAudio(key, type, posObj, loop, isFade, fadeInTime); } public int PlayAudio(string key, AudioCriManager.EPlayType type, Vector3 pos, bool loop = false, bool isFade = false, float fadeInTime = 4f) { // #if DEVELOPMENT_BUILD || DEBUG // DebugUtil.Log("播放音频:{0}, type:{1}", key, type); // #endif if (!_CheckPath(key)) { DebugUtil.LogG($"无法找到对应音频文件,key:{key}"); return -1; } if (key == Constants.Sound.ERROR_UI || key == Constants.Sound.ERROR_UI_FIGHT) { EventManager.Instance.Send(EventManager.EventName.Audio_ErrorAudioPlay); } return _PlayAudio(key, type, pos, loop, isFade, fadeInTime); } public int PlayAudio() { return -1; } public void InitLimit(int count0, int count1, int count2) { MusicPoolLimit = count0; SoundPoolLimit = count1; SpeakPoolLimit = count2; } public AudioInst GetAudioByID(EPlayType audioType, int id) { if (audioType == EPlayType.Music) { if (_musicAudioDic.ContainsKey(id)) { return _musicAudioDic[id]; } if (_musicAudioLoopDic.ContainsKey(id)) { return _musicAudioLoopDic[id]; } return null; } if (audioType == EPlayType.Sound || audioType == EPlayType.Speak) { if (_soundAudioDic.ContainsKey(id)) { return _soundAudioDic[id]; } if (_soundAudioLoopDic.ContainsKey(id)) { return _soundAudioLoopDic[id]; } return null; } return null; } public AudioInst GetAudioByID(int id) { if (_musicAudioDic.ContainsKey(id)) { return _musicAudioDic[id]; } if (_musicAudioLoopDic.ContainsKey(id)) { return _musicAudioLoopDic[id]; } if (_soundAudioDic.ContainsKey(id)) { return _soundAudioDic[id]; } if (_soundAudioLoopDic.ContainsKey(id)) { return _soundAudioLoopDic[id]; } return null; } public void StopMusicById(int audioID) { if (audioID >= 0) { if(_musicAudioDic.TryGetValue(audioID, out var audio)) { audio.Stop(); } if(_musicAudioLoopDic.TryGetValue(audioID, out var audioLoop)) { audioLoop.Stop(); } } } public void StopSoundByID(int audioID) { if (audioID >= 0) { if(_soundAudioDic.TryGetValue(audioID, out var audio)) { audio.Stop(); } if(_soundAudioLoopDic.TryGetValue(audioID, out var audioLoop)) { audioLoop.Stop(); } } } public void StopByID(int audioID) { if (audioID >= 0) { if(_musicAudioDic.TryGetValue(audioID, out var audio)) { audio.Stop(); } if(_musicAudioLoopDic.TryGetValue(audioID, out var audioLoop)) { audioLoop.Stop(); } if (_soundAudioDic.TryGetValue(audioID, out var soundAudio)) { soundAudio.Stop(); } if(_soundAudioLoopDic.TryGetValue(audioID, out var audioLoop1)) { audioLoop1.Stop(); } } } public void PauseAllSound() { foreach (var kv in _soundAudioDic) { var sound = kv.Value; sound.Pause(); } foreach (var kv in _soundAudioLoopDic) { var sound = kv.Value; sound.Pause(); } } public void ResumeAllSound() { foreach (var kv in _soundAudioDic) { var sound = kv.Value; sound.Resume(); } foreach (var kv in _soundAudioLoopDic) { var sound = kv.Value; sound.Resume(); } } public void StopAllMusic() { // if (_bgmAudio != null) // { // _bgmAudio.Stop(); // } DebugUtil.LogG("StopAllMusic"); foreach (var kv in _musicAudioDic) { var audio = kv.Value; audio.Stop(); } foreach (var kv in _musicAudioLoopDic) { var audio = kv.Value; audio.Stop(); } } public void StopAllSounds() { DebugUtil.LogG("StopAllSounds"); foreach (var kv in _soundAudioDic) { var audio = kv.Value; audio.Stop(); } foreach (var kv in _soundAudioLoopDic) { var audio = kv.Value; audio.Stop(); } } public void StopAllSpeaks() { DebugUtil.LogG("StopAllSpeaks"); foreach (var kv in _soundAudioDic) { var audio = kv.Value; if(audio.IsSpeak) audio.Stop(); } } public void StopAll() { DebugUtil.LogG("StopAll"); foreach (var kv in _allAudioDic) { var audio = kv.Value; audio.Stop(); } } public void StopWithFadeByID(int audioID, float fadeOutTime = 1f) { if (audioID >= 0) { if(_musicAudioDic.TryGetValue(audioID, out var audio)) { audio.StopWithFade(fadeOutTime); } if(_musicAudioLoopDic.TryGetValue(audioID, out var audioLoop)) { audioLoop.StopWithFade(fadeOutTime); } if (_soundAudioDic.TryGetValue(audioID, out var soundAudio)) { soundAudio.StopWithFade(fadeOutTime); } if(_soundAudioLoopDic.TryGetValue(audioID, out var audioLoop1)) { audioLoop1.StopWithFade(fadeOutTime); } } } public void ResumeAllMusic() { // if (_bgmAudio != null) // { // _bgmAudio.Resume(); // } foreach (var kv in _musicAudioDic) { var audio = kv.Value; audio.Resume(); } foreach (var kv in _musicAudioLoopDic) { var audio = kv.Value; audio.Resume(); } } public void StopBGM() { _bgmAudioCri.Stop(); } public void AfterSwitchMainCamera(Camera camera) { //if(AudioManager.Instance.GlobalIsSpeakOpen) var listener = camera.GetComponent(); if (listener) { Object.DestroyImmediate(listener); } } // public CriAtomExAcb GetAcb(string cueSheetName) // { // return this.CriAtom.GetAcb(cueSheetName); // } public AudioInst GetStoryAudioInst(AudioBase.AudioType audioType) { return _CreateStoryAudio(null, audioType); } public void ReleaseStoryAudios() { foreach (var kv in _storyAudioDic) { var audio = kv.Value; audio.Stop(); Object.Destroy(audio.RootGo); _allAudioDic.Remove(audio.audioID); } _storyAudioDic.Clear(); } public void PlayByCueName(int audioID, string cueName, bool isFade = false, float fadeOutTime = 4f) { if (_allAudioDic.TryGetValue(audioID, out var audio)) { var fullPath = GetFullPath(cueName); if (isFade) { audio.PlayWithFade(fullPath, fadeOutTime); } else { audio.Play(fullPath); } } } public void PlayByCueName(int audioID, string cueName, float fadeInTime, float targetVolume) { if (_allAudioDic.TryGetValue(audioID, out var audio)) { var fullPath = GetFullPath(cueName); audio.SetTargetVolume(targetVolume); audio.PlayWithFade(fullPath, fadeInTime); } } public void ReleaseMusicAudios() { var musicAudioList = _musicAudioDic.ToList(); for (int i = musicAudioList.Count - 1; i >= 0; i--) { var kv = musicAudioList[i]; var audio = kv.Value; var audioID = kv.Key; audio.Stop(); _musicAudioDic.Remove(audioID); _allAudioDic.Remove(audioID); Object.Destroy(audio.RootGo); } var musicAudioLoopList = _musicAudioLoopDic.ToList(); for (int i = musicAudioLoopList.Count - 1; i >= 0; i--) { var kv = musicAudioLoopList[i]; var audio = kv.Value; var audioID = kv.Key; audio.Stop(); _musicAudioLoopDic.Remove(audioID); _allAudioDic.Remove(audioID); Object.Destroy(audio.RootGo); } _musicAudioObj.Clear(); _musicAudioDic.Clear(); _musicAudioLoopObj.Clear(); _musicAudioLoopDic.Clear(); } public void ReleaseSoundsAudios() { var soundAudioList = _soundAudioDic.ToList(); for (int i = soundAudioList.Count - 1; i >= 0; i--) { var kv = soundAudioList[i]; var audio = kv.Value; var audioID = kv.Key; audio.Stop(); _soundAudioDic.Remove(audioID); _allAudioDic.Remove(audioID); Object.Destroy(audio.RootGo); } var soundAudioLoopList = _soundAudioLoopDic.ToList(); for (int i = soundAudioLoopList.Count - 1; i >= 0; i--) { var kv = soundAudioLoopList[i]; var audio = kv.Value; var audioID = kv.Key; audio.Stop(); _soundAudioLoopDic.Remove(audioID); _allAudioDic.Remove(audioID); Object.Destroy(audio.RootGo); } _soundAudioObj.Clear(); _soundAudioDic.Clear(); _soundAudioLoopObj.Clear(); _soundAudioLoopDic.Clear(); } public void ReleaseAllAudios() { ReleaseMusicAudios(); ReleaseSoundsAudios(); foreach (var playTypeAudios in _playingLDic) { playTypeAudios.Value.Clear(); } _allAudioDic.Clear(); AudioUnity.ResetPlayID(); } // public long GetCueLength(string cueSheet, string cueName) // { // var acb = CriAtom.GetCueSheetInternal(cueSheet).acb; // if (acb.GetCueInfo(cueName, out var cueInfo)) // { // var length = cueInfo.length / 1000; // return length; // } // // return -1; // } public void Add2Playing(AudioBase.AudioType audioType, int id, bool isSpeak = false) { PlayType type; if (audioType == AudioBase.AudioType.Music) { type = PlayType.Music; } else { if (isSpeak) type = PlayType.Speak; else { type = PlayType.Sound; } } var list = _playingLDic[type]; if (!list.Contains(id)) { list.Add(id); } } public void RemovePlaying(AudioBase.AudioType audioType, int id, bool isSpeak = false) { PlayType type; if (audioType == AudioBase.AudioType.Music) { type = PlayType.Music; } else { if (isSpeak) type = PlayType.Speak; else { type = PlayType.Sound; } } var list = _playingLDic[type]; if (list.Contains(id)) { list.Remove(id); } } public void RemovePlaying(int id) { foreach (var kv in _playingLDic) { var list = kv.Value; if (list.Contains(id)) { list.Remove(id); } } } public async UniTask GetClipLength(string key) { var path = GetFullPath(key); var clip = await AssetManager.Instance.LoadAssetAsync(path); if (clip) { return clip.length; } return -1; } public AudioInst GetSoundByPlayID(long playID) { foreach (var kv in _soundAudioDic) { var audio = kv.Value; if (audio.PlayID == playID) { return audio; } } foreach (var kv in _soundAudioLoopDic) { var audio = kv.Value; if (audio.PlayID == playID) { return audio; } } return null; } #endregion #region Listener private void _SetListenerPos() { if (AudioRoot && _isFollowCamera) { var camera = CameraManager.Instance.MainCamera; if (camera) { AudioRoot.transform.position = camera.transform.position; } } } private void _InitListenerPos() { AudioRoot.transform.position = new Vector3(0, 0, 0); } public void EnterFollowState() { _isFollowCamera = true; } public void ExitFollowState() { _isFollowCamera = false; _InitListenerPos(); } #endregion #region Events private void _OnErrorAudioPlay() { foreach (var kv in _soundAudioDic) { var sound = kv.Value; if (sound.IsPlaying) { if (sound.Clip.name == Constants.Sound.COMMON_CLAIM || sound.Clip.name == Constants.Sound.COMMON_CLICK) { sound.Stop(); } } } } #endregion } public struct AudioInfo { public bool persist; public float volume; public float fadeInValue; public float fadeOutValue; public bool isSpeak; } public class AudioInst : AudioUnity { public AudioInst(AudioType audioType, GameObject rootGo, GameObject posGo, AudioInfo audioInfo = new(), bool loop = false, bool is3D = false):base(audioType, rootGo, posGo, audioInfo, loop, is3D) { } public void GetSpectrumData(float[] spectrums) { _audioSource.GetSpectrumData(spectrums, 0, FFTWindow.Blackman); } }