1335 lines
35 KiB
C#
1335 lines
35 KiB
C#
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using Cysharp.Threading.Tasks;
|
||
using Framework;
|
||
using PhxhSDK;
|
||
using UnityEngine;
|
||
using UnityEngine.Audio;
|
||
using Constants = Framework.Constants;
|
||
using Object = UnityEngine.Object;
|
||
|
||
public class AudioUnityManager: Singlenton<AudioUnityManager>, IStart, IInitable, IUpdatable
|
||
{
|
||
public GameObject initGameObject;
|
||
public GameObject AudioRoot;
|
||
private AudioPlayer _bgmAudio;
|
||
|
||
/// <summary>
|
||
/// 对象池数量限制
|
||
/// </summary>
|
||
public int MusicPoolLimit = 1;
|
||
public int SoundPoolLimit = 100;
|
||
public int SpeakPoolLimit = 1;
|
||
|
||
/// <summary>
|
||
/// 播放音频对象池
|
||
/// </summary>
|
||
private Dictionary<int, AudioPlayer> _soundAudioDic;
|
||
private Dictionary<int, AudioPlayer> _soundAudioLoopDic;
|
||
private Dictionary<int, AudioPlayer> _musicAudioDic;
|
||
private Dictionary<int, AudioPlayer> _musicAudioLoopDic;
|
||
private Dictionary<int, AudioPlayer> _allAudioDic;
|
||
|
||
private Dictionary<string, long> _playSoundTimeStampDic; //时间戳记录
|
||
|
||
private Dictionary<AudioPlayType, List<int>> _playingLDic;
|
||
|
||
private Dictionary<int, AudioPlayer> _storyAudioDic;
|
||
|
||
public AudioListener GlobalListener; //全局监听
|
||
private bool _isFollowCamera = false; //是否跟随相机
|
||
|
||
|
||
#region Property
|
||
|
||
/// <summary>
|
||
/// 音效音量 - 委托到 AudioVolumeSettings
|
||
/// </summary>
|
||
public float GlobalSoundsVolume
|
||
{
|
||
get => AudioVolumeSettings.Instance.SoundVolume;
|
||
set => AudioVolumeSettings.Instance.SoundVolume = value;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 语音音量 - 委托到 AudioVolumeSettings
|
||
/// </summary>
|
||
public float GlobalSpeakVolume
|
||
{
|
||
get => AudioVolumeSettings.Instance.SpeakVolume;
|
||
set => AudioVolumeSettings.Instance.SpeakVolume = value;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 音乐音量 - 委托到 AudioVolumeSettings
|
||
/// </summary>
|
||
public float GlobalMusicVolume
|
||
{
|
||
get => AudioVolumeSettings.Instance.MusicVolume;
|
||
set => AudioVolumeSettings.Instance.MusicVolume = value;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 全局总音量 - 委托到 AudioVolumeSettings
|
||
/// </summary>
|
||
public float GlobalVolume
|
||
{
|
||
get => AudioVolumeSettings.Instance.GlobalVolume;
|
||
set => AudioVolumeSettings.Instance.GlobalVolume = value;
|
||
}
|
||
|
||
public bool GlobalIsOpenSpeak;
|
||
|
||
public AudioPlayer BgmAudio
|
||
{
|
||
get { return _bgmAudio; }
|
||
set { _bgmAudio = value; }
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
#region Framework
|
||
|
||
public void Start()
|
||
{
|
||
if (!AudioRoot)
|
||
{
|
||
AudioRoot = new GameObject();
|
||
AudioRoot.name = "Audio(Singleton)";
|
||
Object.DontDestroyOnLoad(AudioRoot);
|
||
GlobalListener = AudioRoot.AddComponent<AudioListener>();
|
||
_InitListenerPos();
|
||
}
|
||
}
|
||
|
||
public void Init()
|
||
{
|
||
_soundAudioDic = new Dictionary<int, AudioPlayer>();
|
||
_soundAudioLoopDic = new Dictionary<int, AudioPlayer>();
|
||
_musicAudioDic = new Dictionary<int, AudioPlayer>();
|
||
_musicAudioLoopDic = new Dictionary<int, AudioPlayer>();
|
||
|
||
_allAudioDic = new Dictionary<int, AudioPlayer>();
|
||
_playingLDic = new ();
|
||
_playingLDic.Add(AudioPlayType.Music, new List<int>());
|
||
_playingLDic.Add(AudioPlayType.Sound, new List<int>());
|
||
_playingLDic.Add(AudioPlayType.Speak, new List<int>());
|
||
|
||
_storyAudioDic = new();
|
||
_playSoundTimeStampDic = 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 string GetFullPath(string key, bool isI18N = false)
|
||
{
|
||
var cfg = TableManager.Instance.Tables.AudioSourceConfig.GetOrDefault(key);
|
||
if (cfg == null)
|
||
{
|
||
DebugUtil.LogError($"音频Key:{key}找不到!");
|
||
return "";
|
||
}
|
||
|
||
var path = cfg.Path;
|
||
if (isI18N)
|
||
{
|
||
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;
|
||
}
|
||
|
||
private float _GetNormalizeVolume(string key)
|
||
{
|
||
var cfg = TableManager.Instance.Tables.AudioSourceConfig.GetOrDefault(key);
|
||
if (cfg == null)
|
||
{
|
||
DebugUtil.LogError($"音频Key:{key}找不到!");
|
||
return 0f;
|
||
}
|
||
|
||
var volume = cfg.VolumeScale;
|
||
return volume;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region AudioObj
|
||
|
||
/// <summary>
|
||
/// 获取可用的Audio
|
||
/// </summary>
|
||
/// <param name="audioType"></param>
|
||
/// <returns></returns>
|
||
private AudioPlayer _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 AudioPlayer _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 AudioPlayType GetPlayType(AudioBase.AudioType audioType, bool isSpeak)
|
||
{
|
||
if (isSpeak)
|
||
return AudioPlayType.Speak;
|
||
if (audioType == AudioBase.AudioType.Music)
|
||
return AudioPlayType.Music;
|
||
return AudioPlayType.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<int, AudioPlayer> _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 AudioPlayer _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 AudioPlayer _CreateStoryAudio(GameObject posGo = null, AudioBase.AudioType audioType = AudioBase.AudioType.Sound)
|
||
{
|
||
var rootGo = new GameObject()
|
||
{
|
||
name = "AudioStory"
|
||
};
|
||
rootGo.transform.SetParent(AudioRoot.transform);
|
||
var audio = new AudioPlayer(audioType, rootGo, null, new AudioInfo(), false, false);
|
||
rootGo.name += audio.audioID;
|
||
_storyAudioDic.TryAdd(audio.audioID, audio);
|
||
_allAudioDic.Add(audio.audioID, audio);
|
||
return audio;
|
||
}
|
||
|
||
private AudioPlayer _CreateNewAudio(AudioBase.AudioType audioType, bool isLoop)
|
||
{
|
||
var rootGo = new GameObject()
|
||
{
|
||
name = "Audio"
|
||
};
|
||
rootGo.transform.SetParent(AudioRoot.transform);
|
||
var audio = new AudioPlayer(audioType, rootGo, null, new AudioInfo(), false, false);
|
||
|
||
if (audioType == AudioBase.AudioType.Music)
|
||
{
|
||
rootGo.name = "music";
|
||
rootGo.name += audio.audioID;
|
||
if (isLoop)
|
||
{
|
||
rootGo.name += "Loop";
|
||
_musicAudioLoopDic.TryAdd(audio.audioID, audio);
|
||
}
|
||
else
|
||
{
|
||
_musicAudioDic.TryAdd(audio.audioID, audio);
|
||
}
|
||
}
|
||
if (audioType == AudioBase.AudioType.Sound)
|
||
{
|
||
rootGo.name = "Sound";
|
||
rootGo.name += audio.audioID;
|
||
if (isLoop)
|
||
{
|
||
rootGo.name += "Loop";
|
||
_soundAudioLoopDic.TryAdd(audio.audioID, audio);
|
||
}
|
||
else
|
||
{
|
||
_soundAudioDic.TryAdd(audio.audioID, audio);
|
||
}
|
||
}
|
||
_allAudioDic.Add(audio.audioID, audio);
|
||
|
||
return audio;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Play
|
||
|
||
/// <summary>
|
||
/// 调用接口,传obj
|
||
/// </summary>
|
||
/// <param name="key"></param>
|
||
/// <param name="type"></param>
|
||
/// <param name="posObj"></param>
|
||
/// <returns></returns>
|
||
private int _PlayAudio(string key, AudioPlayType type, GameObject posObj = null, bool isLoop = false,
|
||
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeTime = 0f)
|
||
{
|
||
var settings = AudioVolumeSettings.Instance;
|
||
switch (type)
|
||
{
|
||
case AudioPlayType.Sound:
|
||
if (settings.GlobalVolume <= 0 || settings.SoundVolume <= 0)
|
||
{
|
||
return -1;
|
||
}
|
||
break;
|
||
case AudioPlayType.Speak:
|
||
if (settings.GlobalVolume <= 0 || settings.SpeakVolume <= 0)
|
||
{
|
||
return -1;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
if (string.IsNullOrEmpty(key))
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
switch (type)
|
||
{
|
||
case AudioPlayType.Music:
|
||
{
|
||
return _PlayMusic(key, posObj, isLoop, isFade, fadeTime);
|
||
}
|
||
case AudioPlayType.Sound:
|
||
{
|
||
return _PlaySound(key, posObj, isLoop, priority, isFade, fadeTime);
|
||
}
|
||
case AudioPlayType.Speak:
|
||
{
|
||
return _PlaySpeakSound(key, posObj, isFade, fadeTime);
|
||
}
|
||
default: break;
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 调用接口,传位置
|
||
/// </summary>
|
||
/// <param name="key"></param>
|
||
/// <param name="type"></param>
|
||
/// <param name="pos"></param>
|
||
/// <returns></returns>
|
||
private int _PlayAudio(string key, AudioPlayType type, Vector3 pos, bool loop = false,
|
||
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeTime = 0f)
|
||
{
|
||
var settings = AudioVolumeSettings.Instance;
|
||
switch (type)
|
||
{
|
||
case AudioPlayType.Sound:
|
||
if (settings.GlobalVolume <= 0 || settings.SoundVolume <= 0)
|
||
{
|
||
return -1;
|
||
}
|
||
break;
|
||
case AudioPlayType.Speak:
|
||
if (settings.GlobalVolume <= 0 || settings.SpeakVolume <= 0)
|
||
{
|
||
return -1;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
switch (type)
|
||
{
|
||
case AudioPlayType.Music:
|
||
{
|
||
return _PlayMusic(key, pos, loop, isFade, fadeTime);
|
||
}
|
||
case AudioPlayType.Sound:
|
||
{
|
||
return _PlaySound(key, pos, loop, priority, isFade, fadeTime);
|
||
}
|
||
case AudioPlayType.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)
|
||
{
|
||
var path = GetFullPath(key);
|
||
if (!isFade)
|
||
{
|
||
var audio = _GetUsableAudio(AudioBase.AudioType.Music, isLoop);
|
||
|
||
//错误打印,保护
|
||
if (audio == null)
|
||
{
|
||
DebugUtil.LogError($"AudioManager, PlayMusic, Cant GetUsableAudio key:{key}");
|
||
return -1;
|
||
}
|
||
|
||
var norVol = _GetNormalizeVolume(key);
|
||
audio.SetNormalizeVolume(norVol);
|
||
audio.SetPosObj(posObj);
|
||
audio.SetIsSpeak(false);
|
||
audio.SetTargetVolume(volume * norVol);
|
||
audio.SetIsLoop(isLoop);
|
||
audio.Play(path);
|
||
audio.SetIsLoop(isLoop);
|
||
return audio.audioID;
|
||
}
|
||
else
|
||
{
|
||
var audio = _GetUsableAudio(AudioBase.AudioType.Music, isLoop);
|
||
audio.SetPosObj(posObj);
|
||
audio.SetIsSpeak(false);
|
||
audio.Stop();
|
||
audio.SetTargetVolume(0);
|
||
audio.PlayWithFade(path, fadeTime);
|
||
audio.SetIsLoop(isLoop);
|
||
return audio.audioID;
|
||
}
|
||
}
|
||
|
||
private int _PlayMusic(string key, Vector3 pos, bool isLoop, bool isFade = false, float fadeTime = 0f, float volume = 1f)
|
||
{
|
||
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);
|
||
|
||
var norVol = _GetNormalizeVolume(key);
|
||
audio.SetNormalizeVolume(norVol);
|
||
|
||
audio.SetIsLoop(true);
|
||
audio.Stop();
|
||
if (isFade)
|
||
{
|
||
audio.SetTargetVolume(0);
|
||
audio.SetTargetVolume(volume);
|
||
audio.PlayWithFade(path, fadeTime);
|
||
}
|
||
else
|
||
{
|
||
audio.Play(path);
|
||
}
|
||
|
||
audio.SetIsLoop(isLoop);
|
||
return audio.audioID;
|
||
}
|
||
|
||
private int _PlaySound(string key, GameObject posObj = null, bool isLoop = false,
|
||
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeTime = 0f, float volume = 1f)
|
||
{
|
||
if (GlobalSoundsVolume < 0.01f)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
//判断优先级然后设置间隔
|
||
if (priority >= AudioConstant.LowPriority)
|
||
{
|
||
var curTimeStamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||
if (_playSoundTimeStampDic.TryGetValue(key, out var timeStamp))
|
||
{
|
||
if (curTimeStamp - timeStamp < 100)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
_playSoundTimeStampDic[key] = curTimeStamp;
|
||
}
|
||
else
|
||
{
|
||
_playSoundTimeStampDic.TryAdd(key, curTimeStamp);
|
||
}
|
||
}
|
||
|
||
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();
|
||
|
||
var norVol = _GetNormalizeVolume(key);
|
||
audio.SetNormalizeVolume(norVol);
|
||
audio.SetPosObj(posObj);
|
||
audio.SetIsSpeak(false);
|
||
audio.SetIsLoop(isLoop);
|
||
if (posObj)
|
||
{
|
||
audio.SetIs3D(true);
|
||
}
|
||
|
||
if (isFade)
|
||
{
|
||
audio.SetTargetVolume(0);
|
||
audio.PlayWithFade(path);
|
||
}
|
||
else
|
||
{
|
||
audio.SetTargetVolume(volume * norVol);
|
||
audio.Play(path);
|
||
}
|
||
|
||
audio.SetIsLoop(isLoop);
|
||
return audio.audioID;
|
||
}
|
||
|
||
private int _PlaySound(string key, Vector3 pos, bool isLoop = false, int priority = AudioConstant.DefaultPriority,
|
||
bool isFade = false, float fadeTime = 0f, float volume = 1f)
|
||
{
|
||
if (GlobalSoundsVolume < 0.01f)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
//判断优先级然后设置间隔
|
||
if (priority >= AudioConstant.LowPriority)
|
||
{
|
||
var curTimeStamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||
if (_playSoundTimeStampDic.TryGetValue(key, out var timeStamp))
|
||
{
|
||
if (curTimeStamp - timeStamp < 100)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
_playSoundTimeStampDic[key] = curTimeStamp;
|
||
}
|
||
else
|
||
{
|
||
_playSoundTimeStampDic.TryAdd(key, curTimeStamp);
|
||
}
|
||
}
|
||
|
||
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();
|
||
|
||
var norVol = _GetNormalizeVolume(key);
|
||
audio.SetNormalizeVolume(norVol);
|
||
audio.SetPos(pos);
|
||
audio.SetIsLoop(isLoop);
|
||
audio.SetIsSpeak(false);
|
||
audio.SetIs3D(true);
|
||
if (isFade)
|
||
{
|
||
audio.SetTargetVolume(0);
|
||
audio.PlayWithFade(path, fadeTime);
|
||
}
|
||
else
|
||
{
|
||
audio.SetTargetVolume(volume * norVol);
|
||
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;
|
||
}
|
||
|
||
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);
|
||
|
||
var norVol = _GetNormalizeVolume(key);
|
||
audio.SetNormalizeVolume(norVol);
|
||
audio.SetPosObj(posObj);
|
||
audio.SetIsSpeak(true);
|
||
|
||
if (isFade)
|
||
{
|
||
audio.SetTargetVolume(0);
|
||
audio.PlayWithFade(path, fadeTime);
|
||
}
|
||
else
|
||
{
|
||
audio.SetTargetVolume(volume * norVol);
|
||
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)
|
||
{
|
||
var audio = _GetUsableAudio(AudioBase.AudioType.Sound, false);
|
||
var path = GetFullPath(key, true);
|
||
var norVol = _GetNormalizeVolume(key);
|
||
audio.SetNormalizeVolume(norVol);
|
||
audio.SetPos(pos);
|
||
audio.SetIsSpeak(true);
|
||
if (isFade)
|
||
{
|
||
audio.SetTargetVolume(0);
|
||
audio.PlayWithFade(path, fadeTime);
|
||
}
|
||
else
|
||
{
|
||
audio.SetTargetVolume(volume * norVol);
|
||
audio.Play(path);
|
||
}
|
||
audio.SetIsLoop(false);
|
||
return audio.audioID;
|
||
}
|
||
|
||
|
||
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, AudioPlayType type, GameObject posObj = null, bool loop = false,
|
||
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeInTime = 4f)
|
||
{
|
||
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, priority, isFade, fadeInTime);
|
||
}
|
||
|
||
public int PlayAudio(string key, AudioPlayType type, Vector3 pos, bool loop = false,
|
||
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeInTime = 4f)
|
||
{
|
||
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, priority, isFade, fadeInTime);
|
||
}
|
||
|
||
public void InitLimit(int count0, int count1, int count2)
|
||
{
|
||
MusicPoolLimit = count0;
|
||
SoundPoolLimit = count1;
|
||
SpeakPoolLimit = count2;
|
||
}
|
||
|
||
public AudioPlayer GetAudioByID(AudioPlayType audioType, int id)
|
||
{
|
||
if (audioType == AudioPlayType.Music)
|
||
{
|
||
if (_musicAudioDic.ContainsKey(id))
|
||
{
|
||
return _musicAudioDic[id];
|
||
}
|
||
|
||
if (_musicAudioLoopDic.ContainsKey(id))
|
||
{
|
||
return _musicAudioLoopDic[id];
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
if (audioType == AudioPlayType.Sound || audioType == AudioPlayType.Speak)
|
||
{
|
||
if (_soundAudioDic.ContainsKey(id))
|
||
{
|
||
return _soundAudioDic[id];
|
||
}
|
||
|
||
if (_soundAudioLoopDic.ContainsKey(id))
|
||
{
|
||
return _soundAudioLoopDic[id];
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
public AudioPlayer 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()
|
||
{
|
||
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()
|
||
{
|
||
foreach (var kv in _musicAudioDic)
|
||
{
|
||
var audio = kv.Value;
|
||
audio.Resume();
|
||
}
|
||
|
||
foreach (var kv in _musicAudioLoopDic)
|
||
{
|
||
var audio = kv.Value;
|
||
audio.Resume();
|
||
}
|
||
}
|
||
|
||
public void AfterSwitchMainCamera(Camera camera)
|
||
{
|
||
//if(AudioManager.Instance.GlobalIsSpeakOpen)
|
||
var listener = camera.GetComponent<AudioListener>();
|
||
if (listener)
|
||
{
|
||
Object.DestroyImmediate(listener);
|
||
}
|
||
}
|
||
|
||
public AudioPlayer 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 PlayByKey(int audioID, string key, bool isFade = false, float fadeOutTime = 4f)
|
||
{
|
||
if (_allAudioDic.TryGetValue(audioID, out var audio))
|
||
{
|
||
var fullPath = GetFullPath(key);
|
||
if (isFade)
|
||
{
|
||
audio.PlayWithFade(fullPath, fadeOutTime);
|
||
}
|
||
else
|
||
{
|
||
audio.Play(fullPath);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void PlayByKey(int audioID, string key, float fadeInTime, float targetVolume)
|
||
{
|
||
if (_allAudioDic.TryGetValue(audioID, out var audio))
|
||
{
|
||
var fullPath = GetFullPath(key);
|
||
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);
|
||
}
|
||
|
||
_musicAudioDic.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);
|
||
}
|
||
|
||
_soundAudioDic.Clear();
|
||
_soundAudioLoopDic.Clear();
|
||
_playSoundTimeStampDic.Clear();
|
||
}
|
||
|
||
public void ReleaseAllAudios()
|
||
{
|
||
ReleaseMusicAudios();
|
||
ReleaseSoundsAudios();
|
||
foreach (var playTypeAudios in _playingLDic)
|
||
{
|
||
playTypeAudios.Value.Clear();
|
||
}
|
||
_allAudioDic.Clear();
|
||
AudioPlayer.ResetPlayID();
|
||
AudioPlayer.ReleaseLoadedAssets();
|
||
}
|
||
|
||
public void Add2Playing(AudioBase.AudioType audioType, int id, bool isSpeak = false)
|
||
{
|
||
AudioPlayType type;
|
||
if (audioType == AudioBase.AudioType.Music)
|
||
{
|
||
type = AudioPlayType.Music;
|
||
}
|
||
else
|
||
{
|
||
if (isSpeak)
|
||
type = AudioPlayType.Speak;
|
||
else
|
||
{
|
||
type = AudioPlayType.Sound;
|
||
}
|
||
}
|
||
var list = _playingLDic[type];
|
||
if (!list.Contains(id))
|
||
{
|
||
list.Add(id);
|
||
}
|
||
}
|
||
|
||
public void RemovePlaying(AudioBase.AudioType audioType, int id, bool isSpeak = false)
|
||
{
|
||
AudioPlayType type;
|
||
if (audioType == AudioBase.AudioType.Music)
|
||
{
|
||
type = AudioPlayType.Music;
|
||
}
|
||
else
|
||
{
|
||
if (isSpeak)
|
||
type = AudioPlayType.Speak;
|
||
else
|
||
{
|
||
type = AudioPlayType.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<float> GetClipLength(string key)
|
||
{
|
||
var path = GetFullPath(key);
|
||
var clip = await AssetManager.Instance.LoadAssetAsync<AudioClip>(path);
|
||
if (clip)
|
||
{
|
||
return clip.length;
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
public AudioPlayer 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;
|
||
} |