NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/Audio/AudioUnityManager.cs

980 lines
27 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 AudioRoot;
/// <summary>
/// 对象池数量限制
/// </summary>
public int MusicPoolLimit = 1;
public int SoundPoolLimit = 100;
public int SpeakPoolLimit = 1;
/// <summary>
/// 播放音频对象池
/// </summary>
// 音频字典合并循环和非循环AudioPlayer.loop 属性可区分)
private Dictionary<int, AudioPlayer> _soundAudioDic;
private Dictionary<int, AudioPlayer> _musicAudioDic;
private Dictionary<int, AudioPlayer> _allAudioDic;
private Dictionary<string, long> _playSoundTimeStampDic; //时间戳记录
// 正在播放的音频ID列表用于限制播放数量
private List<int> _playingMusicList;
private List<int> _playingSoundList;
private List<int> _playingSpeakList;
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;
#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>();
_musicAudioDic = new Dictionary<int, AudioPlayer>();
_allAudioDic = new Dictionary<int, AudioPlayer>();
_playingMusicList = new List<int>();
_playingSoundList = new List<int>();
_playingSpeakList = 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.State != PlayState.Stopped)
{
audio.Update(dt);
}
}
foreach (var kv in _soundAudioDic)
{
var audio = kv.Value;
if (audio.State != PlayState.Stopped)
{
audio.Update(dt);
}
}
foreach (var kv in _storyAudioDic)
{
var audio = kv.Value;
if (audio.State != PlayState.Stopped)
{
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="eAudioType"></param>
/// <returns></returns>
private AudioPlayer _GetUsableAudio(PhxhSDK.EAudioType eAudioType, bool isLoop)
{
try
{
var limit = _CheckIsAudioLimited(eAudioType);
if (limit)
{
return _GetOldAudio(eAudioType);
}
var freeAudio = _GetFreeAudio(eAudioType);
return freeAudio ?? _CreateNewAudio(eAudioType, isLoop);
}
catch (Exception e)
{
DebugUtil.LogError($"AudioManger, GetUsableAudio Fail.{e}");
}
return null;
}
private AudioPlayer _GetOldAudio(PhxhSDK.EAudioType eAudioType)
{
var playingList = _GetPlayingList(eAudioType);
if (playingList.Count > 0)
{
var audio = GetAudioByID(playingList[0]);
return audio;
}
// 如果没有正在播放的音频,创建新的(使用默认不循环)
return _CreateNewAudio(eAudioType, isLoop: false);
}
private int _GetLimit(PhxhSDK.EAudioType eAudioType)
{
switch (eAudioType)
{
case PhxhSDK.EAudioType.Music:
return MusicPoolLimit;
case PhxhSDK.EAudioType.Sound:
return SoundPoolLimit;
case PhxhSDK.EAudioType.Speak:
return SpeakPoolLimit;
default:
return -1;
}
}
private List<int> _GetPlayingList(PhxhSDK.EAudioType eAudioType)
{
switch (eAudioType)
{
case PhxhSDK.EAudioType.Music:
return _playingMusicList;
case PhxhSDK.EAudioType.Sound:
return _playingSoundList;
case PhxhSDK.EAudioType.Speak:
return _playingSpeakList;
default:
return _playingSoundList;
}
}
private bool _CheckIsAudioLimited(PhxhSDK.EAudioType eAudioType)
{
var limit = _GetLimit(eAudioType);
var playingList = _GetPlayingList(eAudioType);
return playingList.Count >= limit;
}
private Dictionary<int, AudioPlayer> _GetAudioDic(PhxhSDK.EAudioType eAudioType)
{
switch (eAudioType)
{
case PhxhSDK.EAudioType.Music:
return _musicAudioDic;
case PhxhSDK.EAudioType.Sound:
return _soundAudioDic;
default:
{
DebugUtil.LogError("获取AudioDic出错传入AudioType有误");
return null;
}
}
}
private AudioPlayer _GetFreeAudio(PhxhSDK.EAudioType eAudioType)
{
var dic = _GetAudioDic(eAudioType);
if (dic != null)
{
foreach (var kv in dic)
{
var audio = kv.Value;
if (audio.State == PlayState.Stopped)
{
return audio;
}
}
}
return null;
}
private AudioPlayer _CreateStoryAudio(GameObject posGo = null, PhxhSDK.EAudioType eAudioType = PhxhSDK.EAudioType.Sound)
{
var rootGo = new GameObject()
{
name = "AudioStory"
};
rootGo.transform.SetParent(AudioRoot.transform);
var audio = new AudioPlayer(eAudioType, 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(PhxhSDK.EAudioType eAudioType, bool isLoop)
{
var rootGo = new GameObject()
{
name = "Audio"
};
rootGo.transform.SetParent(AudioRoot.transform);
var audio = new AudioPlayer(eAudioType, rootGo, null, new AudioInfo(), false, false);
if (eAudioType == PhxhSDK.EAudioType.Music)
{
rootGo.name = $"music{audio.AudioId}";
if (isLoop)
{
rootGo.name += "Loop";
}
_musicAudioDic.TryAdd(audio.AudioId, audio);
}
else if (eAudioType == PhxhSDK.EAudioType.Sound)
{
rootGo.name = $"Sound{audio.AudioId}";
if (isLoop)
{
rootGo.name += "Loop";
}
_soundAudioDic.TryAdd(audio.AudioId, audio);
}
_allAudioDic.Add(audio.AudioId, audio);
return audio;
}
#endregion
#region Play
/// <summary>
/// 调用接口传GameObject
/// </summary>
private int _PlayAudio(string key, PhxhSDK.EAudioType type, GameObject posObj = null, bool isLoop = false,
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeTime = 0f)
{
var settings = AudioVolumeSettings.Instance;
switch (type)
{
case PhxhSDK.EAudioType.Sound:
if (settings.GlobalVolume <= 0 || settings.SoundVolume <= 0)
return -1;
break;
case PhxhSDK.EAudioType.Speak:
if (settings.GlobalVolume <= 0 || settings.SpeakVolume <= 0)
return -1;
break;
}
if (string.IsNullOrEmpty(key))
return -1;
switch (type)
{
case PhxhSDK.EAudioType.Music:
return _PlayMusic(key, posObj, isLoop, isFade, fadeTime);
case PhxhSDK.EAudioType.Sound:
return _PlaySound(key, posObj, isLoop, priority, isFade, fadeTime);
case PhxhSDK.EAudioType.Speak:
return _PlaySpeakSound(key, posObj, isFade, fadeTime);
default:
return -1;
}
}
/// <summary>
/// 调用接口传Vector3位置
/// </summary>
private int _PlayAudio(string key, PhxhSDK.EAudioType type, Vector3 pos, bool loop = false,
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeTime = 0f)
{
var settings = AudioVolumeSettings.Instance;
switch (type)
{
case PhxhSDK.EAudioType.Sound:
if (settings.GlobalVolume <= 0 || settings.SoundVolume <= 0)
return -1;
break;
case PhxhSDK.EAudioType.Speak:
if (settings.GlobalVolume <= 0 || settings.SpeakVolume <= 0)
return -1;
break;
}
switch (type)
{
case PhxhSDK.EAudioType.Music:
return _PlayMusic(key, pos, loop, isFade, fadeTime);
case PhxhSDK.EAudioType.Sound:
return _PlaySound(key, pos, loop, priority, isFade, fadeTime);
case PhxhSDK.EAudioType.Speak:
return _PlaySpeakSound(key, pos, isFade, fadeTime);
default:
return -1;
}
}
private int _PlayMusic(string key, GameObject posObj = null, bool isLoop = true, bool isFade = false, float fadeTime = 0f, float volume = 1f)
{
return _PlayMusicCore(key, isLoop, isFade, fadeTime, volume, posObj, null);
}
private int _PlayMusic(string key, Vector3 pos, bool isLoop, bool isFade = false, float fadeTime = 0f, float volume = 1f)
{
return _PlayMusicCore(key, isLoop, isFade, fadeTime, volume, null, pos);
}
private int _PlayMusicCore(string key, bool isLoop, bool isFade, float fadeTime, float volume,
GameObject followTarget, Vector3? staticPosition)
{
var path = GetFullPath(key);
var audio = _GetUsableAudio(PhxhSDK.EAudioType.Music, isLoop);
if (audio == null)
{
DebugUtil.LogError($"AudioManager, PlayMusic, Cant GetUsableAudio key:{key}");
return -1;
}
return ConfigureAndPlay(audio, path, key, isLoop, isFade, fadeTime, volume,
followTarget, staticPosition, isSpeak: false);
}
private int _PlaySound(string key, GameObject posObj = null, bool isLoop = false,
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeTime = 0f, float volume = 1f)
{
return _PlaySoundCore(key, isLoop, priority, isFade, fadeTime, volume, posObj, null);
}
private int _PlaySound(string key, Vector3 pos, bool isLoop = false, int priority = AudioConstant.DefaultPriority,
bool isFade = false, float fadeTime = 0f, float volume = 1f)
{
return _PlaySoundCore(key, isLoop, priority, isFade, fadeTime, volume, null, pos);
}
private int _PlaySoundCore(string key, bool isLoop, int priority, bool isFade, float fadeTime, float volume,
GameObject followTarget, Vector3? staticPosition)
{
if (GlobalSoundsVolume < 0.01f)
{
return -1;
}
// 防重播检查低优先级音效100ms内防重
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(PhxhSDK.EAudioType.Sound, isLoop);
if (audio == null)
{
DebugUtil.LogError($"AudioManager, PlaySound, Cant GetUsableAudio key:{key}");
return -1;
}
var path = GetFullPath(key);
return ConfigureAndPlay(audio, path, key, isLoop, isFade, fadeTime, volume,
followTarget, staticPosition, isSpeak: false);
}
private int _PlaySpeakSound(string key, GameObject posObj = null, bool isFade = false, float fadeTime = 0f, float volume = 1f)
{
return _PlaySpeakSoundCore(key, isFade, fadeTime, volume, posObj, null);
}
private int _PlaySpeakSound(string key, Vector3 pos, bool isFade = false, float fadeTime = 0f, float volume = 1f)
{
return _PlaySpeakSoundCore(key, isFade, fadeTime, volume, null, pos);
}
private int _PlaySpeakSoundCore(string key, bool isFade, float fadeTime, float volume,
GameObject followTarget, Vector3? staticPosition)
{
if (GlobalSpeakVolume < 0.01f)
{
return -1;
}
var audio = _GetUsableAudio(PhxhSDK.EAudioType.Sound, isLoop: false);
if (audio == null)
{
DebugUtil.LogError($"AudioManager, PlaySpeak, Cant GetUsableAudio key:{key}");
return -1;
}
var path = GetFullPath(key, isI18N: true);
return ConfigureAndPlay(audio, path, key, isLoop: false, isFade, fadeTime, volume,
followTarget, staticPosition, isSpeak: true);
}
/// <summary>
/// 统一的配置和播放核心方法
/// </summary>
private int ConfigureAndPlay(AudioPlayer audio, string path, string key, bool isLoop, bool isFade,
float fadeTime, float volume, GameObject followTarget, Vector3? staticPosition, bool isSpeak)
{
// 1. 设置归一化音量
var norVol = _GetNormalizeVolume(key);
audio.SetNormalizeVolume(norVol);
// 2. 设置语音标记
audio.SetIsSpeak(isSpeak);
// 3. 设置循环(只设置一次,避免重复)
audio.SetLoop(isLoop);
// 4. 设置位置3D音效
if (followTarget != null)
{
audio.SetFollowTarget(followTarget);
audio.SetIs3D(true);
}
else if (staticPosition.HasValue)
{
audio.SetPosition(staticPosition.Value);
audio.SetIs3D(true);
}
else
{
audio.SetIs3D(false);
}
// 5. 播放音频(带淡入或直接播放)
if (isFade)
{
audio.SetVolume(0);
audio.PlayWithFade(path, fadeTime, fadeTime);
}
else
{
audio.SetVolume(volume * norVol);
audio.Play(path);
}
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, PhxhSDK.EAudioType 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, PhxhSDK.EAudioType 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(PhxhSDK.EAudioType eAudioType, int id)
{
switch (eAudioType)
{
case PhxhSDK.EAudioType.Music:
return _musicAudioDic.TryGetValue(id, out var musicAudio) ? musicAudio : null;
case PhxhSDK.EAudioType.Sound:
case PhxhSDK.EAudioType.Speak:
return _soundAudioDic.TryGetValue(id, out var soundAudio) ? soundAudio : null;
default:
return null;
}
}
public AudioPlayer GetAudioByID(int id)
{
if (_musicAudioDic.TryGetValue(id, out var audio))
{
return audio;
}
if (_soundAudioDic.TryGetValue(id, out audio))
{
return audio;
}
return null;
}
public void StopMusicByID(int audioID)
{
if (audioID >= 0 && _musicAudioDic.TryGetValue(audioID, out var audio))
{
audio.Stop();
}
}
public void StopSoundByID(int audioID)
{
if (audioID >= 0 && _soundAudioDic.TryGetValue(audioID, out var audio))
{
audio.Stop();
}
}
public void StopByID(int audioID)
{
if (audioID < 0)
return;
if (_musicAudioDic.TryGetValue(audioID, out var audio))
{
audio.Stop();
return;
}
if (_soundAudioDic.TryGetValue(audioID, out audio))
{
audio.Stop();
}
}
public void PauseAllSound()
{
foreach (var kv in _soundAudioDic)
{
kv.Value.Pause();
}
}
public void ResumeAllSound()
{
foreach (var kv in _soundAudioDic)
{
kv.Value.Resume();
}
}
public void StopAllMusic()
{
DebugUtil.LogG("StopAllMusic");
foreach (var kv in _musicAudioDic)
{
kv.Value.Stop();
}
}
public void StopAllSounds()
{
DebugUtil.LogG("StopAllSounds");
foreach (var kv in _soundAudioDic)
{
kv.Value.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)
return;
if (_musicAudioDic.TryGetValue(audioID, out var audio))
{
audio.StopWithFadeOut(fadeOutTime);
return;
}
if (_soundAudioDic.TryGetValue(audioID, out audio))
{
audio.StopWithFadeOut(fadeOutTime);
}
}
public void ResumeAllMusic()
{
foreach (var kv in _musicAudioDic)
{
kv.Value.Resume();
}
}
public void AfterSwitchMainCamera(Camera camera)
{
//if(AudioManager.Instance.GlobalIsSpeakOpen)
var listener = camera.GetComponent<AudioListener>();
if (listener)
{
Object.DestroyImmediate(listener);
}
}
public AudioPlayer GetStoryAudioInst(PhxhSDK.EAudioType eAudioType)
{
return _CreateStoryAudio(null, eAudioType);
}
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.SetVolume(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);
}
_musicAudioDic.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);
}
_soundAudioDic.Clear();
_playSoundTimeStampDic.Clear();
}
public void ReleaseAllAudios()
{
ReleaseMusicAudios();
ReleaseSoundsAudios();
_playingMusicList.Clear();
_playingSoundList.Clear();
_playingSpeakList.Clear();
_allAudioDic.Clear();
AudioPlayer.ReleaseLoadedAssets();
}
/// <summary>
/// 添加到播放列表(通过 audioID 自动获取类型信息)
/// </summary>
public void Add2Playing(int id)
{
var audio = GetAudioByID(id);
if (audio == null)
return;
// Speak 现在是独立的 EAudioType直接使用 audioType
var list = _GetPlayingList(audio.EAudioType);
if (!list.Contains(id))
{
list.Add(id);
}
}
/// <summary>
/// 从播放列表移除(从所有列表中移除,避免残留)
/// </summary>
public void RemovePlaying(int id)
{
_playingMusicList.Remove(id);
_playingSoundList.Remove(id);
_playingSpeakList.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 GetSoundByAudioID(int audioID)
{
return _soundAudioDic.TryGetValue(audioID, out var audio) ? audio : 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;
}