2025-03-10 13:12:05 +08:00
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
|
|
using Framework;
|
|
|
|
|
|
using PhxhSDK;
|
|
|
|
|
|
using UnityEngine;
|
2025-06-17 17:54:00 +08:00
|
|
|
|
using UnityEngine.Audio;
|
2025-04-16 12:24:10 +08:00
|
|
|
|
using Constants = Framework.Constants;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
using Object = UnityEngine.Object;
|
|
|
|
|
|
|
2025-11-12 20:09:48 +08:00
|
|
|
|
public class AudioUnityManager: Singlenton<AudioUnityManager>, IStart, IInitable, IUpdatable
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
public GameObject AudioRoot;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 对象池数量限制
|
|
|
|
|
|
/// </summary>
|
2025-11-12 19:37:08 +08:00
|
|
|
|
public int MusicPoolLimit = 1;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
public int SoundPoolLimit = 100;
|
|
|
|
|
|
public int SpeakPoolLimit = 1;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 播放音频对象池
|
|
|
|
|
|
/// </summary>
|
2025-11-17 16:47:44 +08:00
|
|
|
|
// 音频字典(合并循环和非循环,AudioPlayer.loop 属性可区分)
|
2025-11-13 16:59:52 +08:00
|
|
|
|
private Dictionary<int, AudioPlayer> _soundAudioDic;
|
|
|
|
|
|
private Dictionary<int, AudioPlayer> _musicAudioDic;
|
|
|
|
|
|
private Dictionary<int, AudioPlayer> _allAudioDic;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
2025-07-21 17:04:43 +08:00
|
|
|
|
private Dictionary<string, long> _playSoundTimeStampDic; //时间戳记录
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
// 正在播放的音频ID列表(用于限制播放数量)
|
|
|
|
|
|
private List<int> _playingMusicList;
|
|
|
|
|
|
private List<int> _playingSoundList;
|
|
|
|
|
|
private List<int> _playingSpeakList;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
2025-11-13 16:59:52 +08:00
|
|
|
|
private Dictionary<int, AudioPlayer> _storyAudioDic;
|
2025-04-02 13:08:43 +08:00
|
|
|
|
|
2025-04-02 15:00:32 +08:00
|
|
|
|
public AudioListener GlobalListener; //全局监听
|
|
|
|
|
|
private bool _isFollowCamera = false; //是否跟随相机
|
2025-06-17 17:54:00 +08:00
|
|
|
|
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
|
|
|
|
|
#region Property
|
|
|
|
|
|
|
2025-11-13 18:36:05 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 音效音量 - 委托到 AudioVolumeSettings
|
|
|
|
|
|
/// </summary>
|
2025-03-10 13:12:05 +08:00
|
|
|
|
public float GlobalSoundsVolume
|
|
|
|
|
|
{
|
2025-11-13 18:36:05 +08:00
|
|
|
|
get => AudioVolumeSettings.Instance.SoundVolume;
|
|
|
|
|
|
set => AudioVolumeSettings.Instance.SoundVolume = value;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
2025-11-13 18:36:05 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 语音音量 - 委托到 AudioVolumeSettings
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float GlobalSpeakVolume
|
|
|
|
|
|
{
|
|
|
|
|
|
get => AudioVolumeSettings.Instance.SpeakVolume;
|
|
|
|
|
|
set => AudioVolumeSettings.Instance.SpeakVolume = value;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 18:36:05 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 音乐音量 - 委托到 AudioVolumeSettings
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float GlobalMusicVolume
|
|
|
|
|
|
{
|
|
|
|
|
|
get => AudioVolumeSettings.Instance.MusicVolume;
|
|
|
|
|
|
set => AudioVolumeSettings.Instance.MusicVolume = value;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 18:36:05 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 全局总音量 - 委托到 AudioVolumeSettings
|
|
|
|
|
|
/// </summary>
|
2025-03-10 13:12:05 +08:00
|
|
|
|
public float GlobalVolume
|
|
|
|
|
|
{
|
2025-11-13 18:36:05 +08:00
|
|
|
|
get => AudioVolumeSettings.Instance.GlobalVolume;
|
|
|
|
|
|
set => AudioVolumeSettings.Instance.GlobalVolume = value;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool GlobalIsOpenSpeak;
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Framework
|
|
|
|
|
|
|
|
|
|
|
|
public void Start()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!AudioRoot)
|
|
|
|
|
|
{
|
|
|
|
|
|
AudioRoot = new GameObject();
|
|
|
|
|
|
AudioRoot.name = "Audio(Singleton)";
|
|
|
|
|
|
Object.DontDestroyOnLoad(AudioRoot);
|
2025-04-02 13:08:43 +08:00
|
|
|
|
GlobalListener = AudioRoot.AddComponent<AudioListener>();
|
2025-04-02 15:00:32 +08:00
|
|
|
|
_InitListenerPos();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Init()
|
|
|
|
|
|
{
|
2025-11-13 16:59:52 +08:00
|
|
|
|
_soundAudioDic = new Dictionary<int, AudioPlayer>();
|
|
|
|
|
|
_musicAudioDic = new Dictionary<int, AudioPlayer>();
|
|
|
|
|
|
_allAudioDic = new Dictionary<int, AudioPlayer>();
|
2025-11-17 19:37:24 +08:00
|
|
|
|
|
|
|
|
|
|
_playingMusicList = new List<int>();
|
|
|
|
|
|
_playingSoundList = new List<int>();
|
|
|
|
|
|
_playingSpeakList = new List<int>();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
|
|
|
|
|
_storyAudioDic = new();
|
2025-07-21 17:04:43 +08:00
|
|
|
|
_playSoundTimeStampDic = new();
|
2025-04-16 12:24:10 +08:00
|
|
|
|
|
|
|
|
|
|
EventManager.Instance.Register(EventManager.EventName.Audio_ErrorAudioPlay, _OnErrorAudioPlay);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Release()
|
|
|
|
|
|
{
|
2025-04-16 12:24:10 +08:00
|
|
|
|
EventManager.Instance.Unregister(EventManager.EventName.Audio_ErrorAudioPlay, _OnErrorAudioPlay);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Update(float dt)
|
|
|
|
|
|
{
|
2025-04-08 16:50:58 +08:00
|
|
|
|
_SetListenerPos();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
foreach (var kv in _musicAudioDic)
|
|
|
|
|
|
{
|
|
|
|
|
|
var audio = kv.Value;
|
2025-11-14 19:10:22 +08:00
|
|
|
|
if (audio.State != PlayState.Stopped)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
audio.Update(dt);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var kv in _soundAudioDic)
|
|
|
|
|
|
{
|
|
|
|
|
|
var audio = kv.Value;
|
2025-11-14 19:10:22 +08:00
|
|
|
|
if (audio.State != PlayState.Stopped)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
audio.Update(dt);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var kv in _storyAudioDic)
|
|
|
|
|
|
{
|
|
|
|
|
|
var audio = kv.Value;
|
2025-11-14 19:10:22 +08:00
|
|
|
|
if (audio.State != PlayState.Stopped)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
audio.Update(dt);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region LoadAsset
|
|
|
|
|
|
|
2025-04-14 14:24:53 +08:00
|
|
|
|
private string GetFullPath(string key, bool isI18N = false)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-03-13 14:58:18 +08:00
|
|
|
|
var cfg = TableManager.Instance.Tables.AudioSourceConfig.GetOrDefault(key);
|
|
|
|
|
|
if (cfg == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError($"音频Key:{key}找不到!");
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
2025-04-14 14:24:53 +08:00
|
|
|
|
|
2025-07-02 15:43:53 +08:00
|
|
|
|
var path = cfg.Path;
|
2025-04-14 14:24:53 +08:00
|
|
|
|
if (isI18N)
|
|
|
|
|
|
{
|
2025-04-24 19:31:27 +08:00
|
|
|
|
if (path.Contains(LanguageManager.I18N))
|
2025-04-14 14:24:53 +08:00
|
|
|
|
{
|
|
|
|
|
|
var eLanguage = LanguageManager.Instance.GetCurrentLanguage();
|
|
|
|
|
|
var replacePath = LanguageManager.PathDic[eLanguage];
|
2025-04-24 19:31:27 +08:00
|
|
|
|
path = path.Replace(LanguageManager.I18N, replacePath);
|
2025-04-14 14:24:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
return path;
|
|
|
|
|
|
}
|
2025-03-13 14:58:18 +08:00
|
|
|
|
return cfg.Path;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
2025-07-28 13:02:07 +08:00
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region AudioObj
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取可用的Audio
|
|
|
|
|
|
/// </summary>
|
2025-11-17 19:37:24 +08:00
|
|
|
|
/// <param name="eAudioType"></param>
|
2025-03-10 13:12:05 +08:00
|
|
|
|
/// <returns></returns>
|
2025-11-17 19:37:24 +08:00
|
|
|
|
private AudioPlayer _GetUsableAudio(PhxhSDK.EAudioType eAudioType, bool isLoop)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
var limit = _CheckIsAudioLimited(eAudioType);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
if (limit)
|
|
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
return _GetOldAudio(eAudioType);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
var freeAudio = _GetFreeAudio(eAudioType);
|
|
|
|
|
|
return freeAudio ?? _CreateNewAudio(eAudioType, isLoop);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError($"AudioManger, GetUsableAudio Fail.{e}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
private AudioPlayer _GetOldAudio(PhxhSDK.EAudioType eAudioType)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
var playingList = _GetPlayingList(eAudioType);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
if (playingList.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
var audio = GetAudioByID(playingList[0]);
|
|
|
|
|
|
return audio;
|
|
|
|
|
|
}
|
2025-11-17 16:47:44 +08:00
|
|
|
|
// 如果没有正在播放的音频,创建新的(使用默认不循环)
|
2025-11-17 19:37:24 +08:00
|
|
|
|
return _CreateNewAudio(eAudioType, isLoop: false);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
private int _GetLimit(PhxhSDK.EAudioType eAudioType)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
switch (eAudioType)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Music:
|
|
|
|
|
|
return MusicPoolLimit;
|
|
|
|
|
|
case PhxhSDK.EAudioType.Sound:
|
|
|
|
|
|
return SoundPoolLimit;
|
|
|
|
|
|
case PhxhSDK.EAudioType.Speak:
|
|
|
|
|
|
return SpeakPoolLimit;
|
|
|
|
|
|
default:
|
|
|
|
|
|
return -1;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
private List<int> _GetPlayingList(PhxhSDK.EAudioType eAudioType)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
switch (eAudioType)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Music:
|
|
|
|
|
|
return _playingMusicList;
|
|
|
|
|
|
case PhxhSDK.EAudioType.Sound:
|
|
|
|
|
|
return _playingSoundList;
|
|
|
|
|
|
case PhxhSDK.EAudioType.Speak:
|
|
|
|
|
|
return _playingSpeakList;
|
|
|
|
|
|
default:
|
|
|
|
|
|
return _playingSoundList;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
2025-11-17 19:37:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool _CheckIsAudioLimited(PhxhSDK.EAudioType eAudioType)
|
|
|
|
|
|
{
|
|
|
|
|
|
var limit = _GetLimit(eAudioType);
|
|
|
|
|
|
var playingList = _GetPlayingList(eAudioType);
|
|
|
|
|
|
return playingList.Count >= limit;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
private Dictionary<int, AudioPlayer> _GetAudioDic(PhxhSDK.EAudioType eAudioType)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
switch (eAudioType)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Music:
|
2025-11-17 16:47:44 +08:00
|
|
|
|
return _musicAudioDic;
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Sound:
|
2025-11-17 16:47:44 +08:00
|
|
|
|
return _soundAudioDic;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
default:
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError("获取AudioDic出错!!!传入AudioType有误!");
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
private AudioPlayer _GetFreeAudio(PhxhSDK.EAudioType eAudioType)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
var dic = _GetAudioDic(eAudioType);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
if (dic != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var kv in dic)
|
|
|
|
|
|
{
|
|
|
|
|
|
var audio = kv.Value;
|
2025-11-14 19:10:22 +08:00
|
|
|
|
if (audio.State == PlayState.Stopped)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
return audio;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
private AudioPlayer _CreateStoryAudio(GameObject posGo = null, PhxhSDK.EAudioType eAudioType = PhxhSDK.EAudioType.Sound)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
var rootGo = new GameObject()
|
|
|
|
|
|
{
|
|
|
|
|
|
name = "AudioStory"
|
|
|
|
|
|
};
|
|
|
|
|
|
rootGo.transform.SetParent(AudioRoot.transform);
|
2025-11-17 19:37:24 +08:00
|
|
|
|
var audio = new AudioPlayer(eAudioType, rootGo, null, new AudioInfo(), false, false);
|
2025-11-17 14:50:15 +08:00
|
|
|
|
rootGo.name += audio.AudioId;
|
|
|
|
|
|
_storyAudioDic.TryAdd(audio.AudioId, audio);
|
|
|
|
|
|
_allAudioDic.Add(audio.AudioId, audio);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return audio;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
private AudioPlayer _CreateNewAudio(PhxhSDK.EAudioType eAudioType, bool isLoop)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
var rootGo = new GameObject()
|
|
|
|
|
|
{
|
|
|
|
|
|
name = "Audio"
|
|
|
|
|
|
};
|
|
|
|
|
|
rootGo.transform.SetParent(AudioRoot.transform);
|
2025-11-17 19:37:24 +08:00
|
|
|
|
var audio = new AudioPlayer(eAudioType, rootGo, null, new AudioInfo(), false, false);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
if (eAudioType == PhxhSDK.EAudioType.Music)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
rootGo.name = $"music{audio.AudioId}";
|
2025-03-10 13:12:05 +08:00
|
|
|
|
if (isLoop)
|
|
|
|
|
|
{
|
|
|
|
|
|
rootGo.name += "Loop";
|
|
|
|
|
|
}
|
2025-11-17 16:47:44 +08:00
|
|
|
|
_musicAudioDic.TryAdd(audio.AudioId, audio);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
2025-11-17 19:37:24 +08:00
|
|
|
|
else if (eAudioType == PhxhSDK.EAudioType.Sound)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
rootGo.name = $"Sound{audio.AudioId}";
|
2025-03-10 13:12:05 +08:00
|
|
|
|
if (isLoop)
|
|
|
|
|
|
{
|
|
|
|
|
|
rootGo.name += "Loop";
|
|
|
|
|
|
}
|
2025-11-17 16:47:44 +08:00
|
|
|
|
_soundAudioDic.TryAdd(audio.AudioId, audio);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
2025-11-17 16:47:44 +08:00
|
|
|
|
|
2025-11-17 14:50:15 +08:00
|
|
|
|
_allAudioDic.Add(audio.AudioId, audio);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
|
|
|
|
|
return audio;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Play
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-11-17 19:37:24 +08:00
|
|
|
|
/// 调用接口,传GameObject
|
2025-03-10 13:12:05 +08:00
|
|
|
|
/// </summary>
|
2025-11-17 19:37:24 +08:00
|
|
|
|
private int _PlayAudio(string key, PhxhSDK.EAudioType type, GameObject posObj = null, bool isLoop = false,
|
2025-07-22 14:56:44 +08:00
|
|
|
|
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeTime = 0f)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-13 18:36:05 +08:00
|
|
|
|
var settings = AudioVolumeSettings.Instance;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
switch (type)
|
|
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Sound:
|
2025-11-13 18:36:05 +08:00
|
|
|
|
if (settings.GlobalVolume <= 0 || settings.SoundVolume <= 0)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return -1;
|
|
|
|
|
|
break;
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Speak:
|
2025-11-13 18:36:05 +08:00
|
|
|
|
if (settings.GlobalVolume <= 0 || settings.SpeakVolume <= 0)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return -1;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2025-11-17 19:37:24 +08:00
|
|
|
|
|
2025-03-10 13:12:05 +08:00
|
|
|
|
if (string.IsNullOrEmpty(key))
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Music:
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return _PlayMusic(key, posObj, isLoop, isFade, fadeTime);
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Sound:
|
2025-07-22 14:56:44 +08:00
|
|
|
|
return _PlaySound(key, posObj, isLoop, priority, isFade, fadeTime);
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Speak:
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return _PlaySpeakSound(key, posObj, isFade, fadeTime);
|
2025-11-17 19:37:24 +08:00
|
|
|
|
default:
|
|
|
|
|
|
return -1;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-11-17 19:37:24 +08:00
|
|
|
|
/// 调用接口,传Vector3位置
|
2025-03-10 13:12:05 +08:00
|
|
|
|
/// </summary>
|
2025-11-17 19:37:24 +08:00
|
|
|
|
private int _PlayAudio(string key, PhxhSDK.EAudioType type, Vector3 pos, bool loop = false,
|
2025-07-22 14:56:44 +08:00
|
|
|
|
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeTime = 0f)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-13 18:36:05 +08:00
|
|
|
|
var settings = AudioVolumeSettings.Instance;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
switch (type)
|
|
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Sound:
|
2025-11-13 18:36:05 +08:00
|
|
|
|
if (settings.GlobalVolume <= 0 || settings.SoundVolume <= 0)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return -1;
|
|
|
|
|
|
break;
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Speak:
|
2025-11-13 18:36:05 +08:00
|
|
|
|
if (settings.GlobalVolume <= 0 || settings.SpeakVolume <= 0)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return -1;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Music:
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return _PlayMusic(key, pos, loop, isFade, fadeTime);
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Sound:
|
2025-07-22 14:56:44 +08:00
|
|
|
|
return _PlaySound(key, pos, loop, priority, isFade, fadeTime);
|
2025-11-17 19:37:24 +08:00
|
|
|
|
case PhxhSDK.EAudioType.Speak:
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return _PlaySpeakSound(key, pos, isFade, fadeTime);
|
2025-11-17 19:37:24 +08:00
|
|
|
|
default:
|
|
|
|
|
|
return -1;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int _PlayMusic(string key, GameObject posObj = null, bool isLoop = true, bool isFade = false, float fadeTime = 0f, float volume = 1f)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
return _PlayMusicCore(key, isLoop, isFade, fadeTime, volume, posObj, null);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int _PlayMusic(string key, Vector3 pos, bool isLoop, bool isFade = false, float fadeTime = 0f, float volume = 1f)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
2025-03-10 13:12:05 +08:00
|
|
|
|
var path = GetFullPath(key);
|
2025-11-17 19:37:24 +08:00
|
|
|
|
var audio = _GetUsableAudio(PhxhSDK.EAudioType.Music, isLoop);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
|
|
|
|
|
if (audio == null)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
DebugUtil.LogError($"AudioManager, PlayMusic, Cant GetUsableAudio key:{key}");
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 16:47:44 +08:00
|
|
|
|
return ConfigureAndPlay(audio, path, key, isLoop, isFade, fadeTime, volume,
|
|
|
|
|
|
followTarget, staticPosition, isSpeak: false);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int _PlaySound(string key, GameObject posObj = null, bool isLoop = false,
|
2025-07-22 14:56:44 +08:00
|
|
|
|
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeTime = 0f, float volume = 1f)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
return _PlaySoundCore(key, isLoop, priority, isFade, fadeTime, volume, posObj, null);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-22 14:56:44 +08:00
|
|
|
|
private int _PlaySound(string key, Vector3 pos, bool isLoop = false, int priority = AudioConstant.DefaultPriority,
|
|
|
|
|
|
bool isFade = false, float fadeTime = 0f, float volume = 1f)
|
2025-11-17 16:47:44 +08:00
|
|
|
|
{
|
|
|
|
|
|
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)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (GlobalSoundsVolume < 0.01f)
|
|
|
|
|
|
{
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
2025-11-17 16:47:44 +08:00
|
|
|
|
|
|
|
|
|
|
// 防重播检查(低优先级音效100ms内防重)
|
2025-07-22 14:56:44 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-17 16:47:44 +08:00
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
var audio = _GetUsableAudio(PhxhSDK.EAudioType.Sound, isLoop);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
|
|
|
|
|
if (audio == null)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
DebugUtil.LogError($"AudioManager, PlaySound, Cant GetUsableAudio key:{key}");
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var path = GetFullPath(key);
|
2025-11-17 16:47:44 +08:00
|
|
|
|
return ConfigureAndPlay(audio, path, key, isLoop, isFade, fadeTime, volume,
|
|
|
|
|
|
followTarget, staticPosition, isSpeak: false);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int _PlaySpeakSound(string key, GameObject posObj = null, bool isFade = false, float fadeTime = 0f, float volume = 1f)
|
2025-11-17 16:47:44 +08:00
|
|
|
|
{
|
|
|
|
|
|
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)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (GlobalSpeakVolume < 0.01f)
|
|
|
|
|
|
{
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
var audio = _GetUsableAudio(PhxhSDK.EAudioType.Sound, isLoop: false);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
|
|
|
|
|
if (audio == null)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
DebugUtil.LogError($"AudioManager, PlaySpeak, Cant GetUsableAudio key:{key}");
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 16:47:44 +08:00
|
|
|
|
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. 设置归一化音量
|
2025-07-28 13:02:07 +08:00
|
|
|
|
var norVol = _GetNormalizeVolume(key);
|
|
|
|
|
|
audio.SetNormalizeVolume(norVol);
|
2025-11-17 16:47:44 +08:00
|
|
|
|
|
|
|
|
|
|
// 2. 设置语音标记
|
|
|
|
|
|
audio.SetIsSpeak(isSpeak);
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 设置循环(只设置一次,避免重复)
|
|
|
|
|
|
audio.SetLoop(isLoop);
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 设置位置(3D音效)
|
|
|
|
|
|
if (followTarget != null)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
audio.SetFollowTarget(followTarget);
|
|
|
|
|
|
audio.SetIs3D(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (staticPosition.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
audio.SetPosition(staticPosition.Value);
|
|
|
|
|
|
audio.SetIs3D(true);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
audio.SetIs3D(false);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 16:47:44 +08:00
|
|
|
|
// 5. 播放音频(带淡入或直接播放)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
if (isFade)
|
|
|
|
|
|
{
|
2025-11-14 18:21:45 +08:00
|
|
|
|
audio.SetVolume(0);
|
2025-11-17 16:47:44 +08:00
|
|
|
|
audio.PlayWithFade(path, fadeTime, fadeTime);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-11-14 18:21:45 +08:00
|
|
|
|
audio.SetVolume(volume * norVol);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
audio.Play(path);
|
|
|
|
|
|
}
|
2025-11-17 16:47:44 +08:00
|
|
|
|
|
2025-11-17 14:50:15 +08:00
|
|
|
|
return audio.AudioId;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool _CheckPath(string key)
|
|
|
|
|
|
{
|
|
|
|
|
|
var cfg = TableManager.Instance.Tables.AudioSourceConfig;
|
|
|
|
|
|
if (cfg.GetOrDefault(key) != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region API
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
public int PlayAudio(string key, PhxhSDK.EAudioType type, GameObject posObj = null, bool loop = false,
|
2025-07-22 14:56:44 +08:00
|
|
|
|
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeInTime = 4f)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (!_CheckPath(key))
|
|
|
|
|
|
{
|
2025-03-10 14:08:22 +08:00
|
|
|
|
if (DebugUtil.LogEnable)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogG($"无法找到对应音频文件,key:{key}");
|
|
|
|
|
|
}
|
2025-03-10 13:12:05 +08:00
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
2025-04-16 12:24:10 +08:00
|
|
|
|
|
|
|
|
|
|
if (key == Constants.Sound.ERROR_UI || key == Constants.Sound.ERROR_UI_FIGHT)
|
|
|
|
|
|
{
|
|
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.Audio_ErrorAudioPlay);
|
|
|
|
|
|
}
|
2025-07-22 14:56:44 +08:00
|
|
|
|
return _PlayAudio(key, type, posObj, loop, priority, isFade, fadeInTime);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
public int PlayAudio(string key, PhxhSDK.EAudioType type, Vector3 pos, bool loop = false,
|
2025-07-22 14:56:44 +08:00
|
|
|
|
int priority = AudioConstant.DefaultPriority, bool isFade = false, float fadeInTime = 4f)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (!_CheckPath(key))
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogG($"无法找到对应音频文件,key:{key}");
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
2025-04-16 12:24:10 +08:00
|
|
|
|
if (key == Constants.Sound.ERROR_UI || key == Constants.Sound.ERROR_UI_FIGHT)
|
|
|
|
|
|
{
|
|
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.Audio_ErrorAudioPlay);
|
|
|
|
|
|
}
|
2025-07-22 14:56:44 +08:00
|
|
|
|
return _PlayAudio(key, type, pos, loop, priority, isFade, fadeInTime);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void InitLimit(int count0, int count1, int count2)
|
|
|
|
|
|
{
|
|
|
|
|
|
MusicPoolLimit = count0;
|
|
|
|
|
|
SoundPoolLimit = count1;
|
|
|
|
|
|
SpeakPoolLimit = count2;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
public AudioPlayer GetAudioByID(PhxhSDK.EAudioType eAudioType, int id)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
switch (eAudioType)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
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;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 16:59:52 +08:00
|
|
|
|
public AudioPlayer GetAudioByID(int id)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
if (_musicAudioDic.TryGetValue(id, out var audio))
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
return audio;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 16:47:44 +08:00
|
|
|
|
if (_soundAudioDic.TryGetValue(id, out audio))
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
return audio;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 16:04:30 +08:00
|
|
|
|
public void StopMusicByID(int audioID)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
if (audioID >= 0 && _musicAudioDic.TryGetValue(audioID, out var audio))
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
audio.Stop();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void StopSoundByID(int audioID)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
if (audioID >= 0 && _soundAudioDic.TryGetValue(audioID, out var audio))
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
audio.Stop();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void StopByID(int audioID)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
if (audioID < 0)
|
|
|
|
|
|
return;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
2025-11-17 16:47:44 +08:00
|
|
|
|
if (_musicAudioDic.TryGetValue(audioID, out var audio))
|
|
|
|
|
|
{
|
|
|
|
|
|
audio.Stop();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
2025-11-17 16:47:44 +08:00
|
|
|
|
if (_soundAudioDic.TryGetValue(audioID, out audio))
|
|
|
|
|
|
{
|
|
|
|
|
|
audio.Stop();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-06-18 14:00:00 +08:00
|
|
|
|
|
|
|
|
|
|
public void PauseAllSound()
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var kv in _soundAudioDic)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
kv.Value.Pause();
|
2025-06-18 14:00:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ResumeAllSound()
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var kv in _soundAudioDic)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
kv.Value.Resume();
|
2025-06-18 14:00:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
|
|
|
|
|
public void StopAllMusic()
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogG("StopAllMusic");
|
|
|
|
|
|
foreach (var kv in _musicAudioDic)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
kv.Value.Stop();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void StopAllSounds()
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogG("StopAllSounds");
|
|
|
|
|
|
foreach (var kv in _soundAudioDic)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
kv.Value.Stop();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
if (audioID < 0)
|
|
|
|
|
|
return;
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
2025-11-17 16:47:44 +08:00
|
|
|
|
if (_musicAudioDic.TryGetValue(audioID, out var audio))
|
|
|
|
|
|
{
|
|
|
|
|
|
audio.StopWithFadeOut(fadeOutTime);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-03-10 13:12:05 +08:00
|
|
|
|
|
2025-11-17 16:47:44 +08:00
|
|
|
|
if (_soundAudioDic.TryGetValue(audioID, out audio))
|
|
|
|
|
|
{
|
|
|
|
|
|
audio.StopWithFadeOut(fadeOutTime);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ResumeAllMusic()
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var kv in _musicAudioDic)
|
|
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
kv.Value.Resume();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void AfterSwitchMainCamera(Camera camera)
|
|
|
|
|
|
{
|
2025-04-02 15:00:32 +08:00
|
|
|
|
//if(AudioManager.Instance.GlobalIsSpeakOpen)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
var listener = camera.GetComponent<AudioListener>();
|
2025-04-02 15:00:32 +08:00
|
|
|
|
if (listener)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-04-02 15:00:32 +08:00
|
|
|
|
Object.DestroyImmediate(listener);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
public AudioPlayer GetStoryAudioInst(PhxhSDK.EAudioType eAudioType)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
return _CreateStoryAudio(null, eAudioType);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ReleaseStoryAudios()
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var kv in _storyAudioDic)
|
|
|
|
|
|
{
|
|
|
|
|
|
var audio = kv.Value;
|
|
|
|
|
|
audio.Stop();
|
|
|
|
|
|
Object.Destroy(audio.RootGo);
|
2025-11-17 14:50:15 +08:00
|
|
|
|
_allAudioDic.Remove(audio.AudioId);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
_storyAudioDic.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-12 19:15:06 +08:00
|
|
|
|
public void PlayByKey(int audioID, string key, bool isFade = false, float fadeOutTime = 4f)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (_allAudioDic.TryGetValue(audioID, out var audio))
|
|
|
|
|
|
{
|
2025-11-12 19:15:06 +08:00
|
|
|
|
var fullPath = GetFullPath(key);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
if (isFade)
|
|
|
|
|
|
{
|
2025-04-14 17:01:03 +08:00
|
|
|
|
audio.PlayWithFade(fullPath, fadeOutTime);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-04-14 17:01:03 +08:00
|
|
|
|
audio.Play(fullPath);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-12 19:15:06 +08:00
|
|
|
|
public void PlayByKey(int audioID, string key, float fadeInTime, float targetVolume)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (_allAudioDic.TryGetValue(audioID, out var audio))
|
|
|
|
|
|
{
|
2025-11-12 19:15:06 +08:00
|
|
|
|
var fullPath = GetFullPath(key);
|
2025-11-14 18:21:45 +08:00
|
|
|
|
audio.SetVolume(targetVolume);
|
2025-04-14 16:03:27 +08:00
|
|
|
|
audio.PlayWithFade(fullPath, fadeInTime);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
2025-07-21 17:04:43 +08:00
|
|
|
|
_playSoundTimeStampDic.Clear();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ReleaseAllAudios()
|
|
|
|
|
|
{
|
|
|
|
|
|
ReleaseMusicAudios();
|
|
|
|
|
|
ReleaseSoundsAudios();
|
2025-11-17 19:37:24 +08:00
|
|
|
|
_playingMusicList.Clear();
|
|
|
|
|
|
_playingSoundList.Clear();
|
|
|
|
|
|
_playingSpeakList.Clear();
|
2025-04-09 17:46:50 +08:00
|
|
|
|
_allAudioDic.Clear();
|
2025-11-13 16:59:52 +08:00
|
|
|
|
AudioPlayer.ReleaseLoadedAssets();
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 添加到播放列表(通过 audioID 自动获取类型信息)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void Add2Playing(int id)
|
2025-03-10 13:12:05 +08:00
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
var audio = GetAudioByID(id);
|
|
|
|
|
|
if (audio == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
// Speak 现在是独立的 EAudioType,直接使用 audioType
|
|
|
|
|
|
var list = _GetPlayingList(audio.EAudioType);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
if (!list.Contains(id))
|
|
|
|
|
|
{
|
|
|
|
|
|
list.Add(id);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-17 19:37:24 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 从播放列表移除(从所有列表中移除,避免残留)
|
|
|
|
|
|
/// </summary>
|
2025-03-10 13:12:05 +08:00
|
|
|
|
public void RemovePlaying(int id)
|
|
|
|
|
|
{
|
2025-11-17 19:37:24 +08:00
|
|
|
|
_playingMusicList.Remove(id);
|
|
|
|
|
|
_playingSoundList.Remove(id);
|
|
|
|
|
|
_playingSpeakList.Remove(id);
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2025-06-24 14:58:32 +08:00
|
|
|
|
|
2025-11-14 20:02:22 +08:00
|
|
|
|
public AudioPlayer GetSoundByAudioID(int audioID)
|
2025-06-24 14:58:32 +08:00
|
|
|
|
{
|
2025-11-17 16:47:44 +08:00
|
|
|
|
return _soundAudioDic.TryGetValue(audioID, out var audio) ? audio : null;
|
2025-06-24 14:58:32 +08:00
|
|
|
|
}
|
2025-03-10 13:12:05 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-04-02 15:00:32 +08:00
|
|
|
|
#region Listener
|
|
|
|
|
|
|
|
|
|
|
|
private void _SetListenerPos()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (AudioRoot && _isFollowCamera)
|
|
|
|
|
|
{
|
|
|
|
|
|
var camera = CameraManager.Instance.MainCamera;
|
2025-04-08 16:50:58 +08:00
|
|
|
|
if (camera)
|
|
|
|
|
|
{
|
|
|
|
|
|
AudioRoot.transform.position = camera.transform.position;
|
|
|
|
|
|
}
|
2025-04-02 15:00:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void _InitListenerPos()
|
|
|
|
|
|
{
|
|
|
|
|
|
AudioRoot.transform.position = new Vector3(0, 0, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void EnterFollowState()
|
|
|
|
|
|
{
|
|
|
|
|
|
_isFollowCamera = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ExitFollowState()
|
|
|
|
|
|
{
|
|
|
|
|
|
_isFollowCamera = false;
|
|
|
|
|
|
_InitListenerPos();
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-04-16 12:24:10 +08:00
|
|
|
|
#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
|
|
|
|
|
|
|
2025-03-10 13:12:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public struct AudioInfo
|
|
|
|
|
|
{
|
|
|
|
|
|
public bool persist;
|
|
|
|
|
|
public float volume;
|
|
|
|
|
|
public float fadeInValue;
|
|
|
|
|
|
public float fadeOutValue;
|
|
|
|
|
|
public bool isSpeak;
|
|
|
|
|
|
}
|