using System; using System.Collections; using System.Threading; using System.Threading.Tasks; using Cysharp.Threading.Tasks; using UnityEngine; namespace Stary.Evo.AudioCore { public class VoicePlayer : AbstractAudio, IDisposable { private AudioSourceToken currentSource; public VoicePlayer(IResources resources) : base(resources) { } /// /// 播放语音 /// /// {[clip:音频], [volume:音量], /// [onComplete:回调行为], [delayOnCompleteTime:延迟回调执行的时间], /// [is3DAudio:是否3D音频], [audio3DPosition:3D音频位置], /// [audio3DMaxDistance:3D音频最大距离]} public override async void Play(AudioData audioData) { AudioSourceToken audioSourceToken = await PlayAudio(audioData); // 使用协程处理延迟和回调 PlayAudioAWait(audioSourceToken, audioData.delayOnCompleteTime, audioData.onComplete, audioData.fadeDuration); } /// /// 异步播放语音 /// /// {[clip:音频], [volume:音量], /// [onComplete:回调行为], [delayOnCompleteTime:延迟回调执行的时间], /// [is3DAudio:是否3D音频], [audio3DPosition:3D音频位置], /// [audio3DMaxDistance:3D音频最大距离], /// [cancellationToken:异步取消令牌]} public override async UniTask PlayAsync(AudioData audioData) { AudioSourceToken audioSourceToken = await PlayAudio(audioData); await PlayAudioAWait(audioSourceToken, audioData.delayOnCompleteTime, audioData.fadeDuration); } private async UniTask PlayAudio(AudioData audioData) { if (Resources == null) { Debug.LogError("AudioCoreManager: Resources is null, please initialize it first."); return null; } // 停止当前正在播放的语音与旧协程,或旧异步 Stop(); audioData = Initialize(audioData); if (!string.IsNullOrEmpty(audioData.packageName) && !string.IsNullOrEmpty(audioData.packageName)) { var clip = await Resources.LoadAssetAsync(audioData.packageName, audioData.assetName); if (clip == null) { Debug.LogErrorFormat($"从资源包【{audioData.packageName}】加载音频片段【{audioData.assetName}】失败"); } else { audioData.clip = clip; } } if (audioData.clip == null) { Debug.LogError("播放的音效音频片段为空"); return null; } AudioSourceToken audioSourceToken = AudioSourcePool.Spawn(); if (audioSourceToken == null) { Debug.LogError("音效池为空,无法播放音效"); return null; } currentSource = audioSourceToken; currentSource.source.clip = audioData.clip; currentSource.source.volume = audioData.volume; // 设置2D与3D音频 if (audioData.is3DAudio) { currentSource.source.transform.position = audioData.audio3DPosition; currentSource.source.spatialBlend = 1; currentSource.source.minDistance = 1f; if (audioData.audio3DMaxDistance != 0) { currentSource.source.maxDistance = audioData.audio3DMaxDistance; } else { // 默认3D最大距离为3米 currentSource.source.maxDistance = 3f; } } else { currentSource.source.transform.position = Vector3.zero; currentSource.source.spatialBlend = 0; currentSource.source.minDistance = 1f; currentSource.source.maxDistance = 500f; } currentSource.source.Play(); FadeInMusic(currentSource.source, audioData.fadeDuration); return audioSourceToken; } /// /// 停止语音 /// /// /// {[无可使用变量]} public override void Stop() { // 停止当前协程 if (currentSource != null && currentSource.source.isPlaying) { currentSource.source.Stop(); AudioSourcePool.RecycleSpawn(currentSource); currentSource = null; } } public override void StopAll() { AudioSourcePool.RecycleAll(); } public override AudioSource GetAudioSource() { return currentSource.source; } public void Dispose() { AudioSourcePool.RecycleAll(); } } }