using System; using System.Collections; using System.Collections.Generic; using Cysharp.Threading.Tasks; using UnityEngine; namespace Stary.Evo.AudioCore { public class SFXPlayer : AbstractAudio, IDisposable { public SFXPlayer(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); } public override async UniTask PlayAsync(AudioData audioData) { AudioSourceToken audioSourceToken = await PlayAudio(audioData); await PlayAudioAWait(audioSourceToken, audioData.delayOnCompleteTime); } private async UniTask PlayAudio(AudioData audioData) { if (Resources == null) { Debug.LogError("AudioCoreManager: Resources is null, please initialize it first."); return null; } 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; } AudioSource source = audioSourceToken.source; source.clip = audioData.clip; source.volume = audioData.volume; // 设置2D与3D音频 if (audioData.is3DAudio) { source.transform.position = audioData.audio3DPosition; source.spatialBlend = 1; source.minDistance = 1f; if (audioData.audio3DMaxDistance != 0) { source.maxDistance = audioData.audio3DMaxDistance; } else { // 默认3D最大距离为3米 source.maxDistance = 3f; } } else { source.transform.position = Vector3.zero; source.spatialBlend = 0; source.minDistance = 1f; source.maxDistance = 500f; } source.Play(); return audioSourceToken; } /// /// 停止所有音效 /// public override void Stop() { AudioSourcePool.RecycleAll(); } public override void StopAll() { AudioSourcePool.RecycleAll(); } public override AudioSource GetAudioSource() { Debug.LogWarning("SFXPlayer: GetAudioSource is not implemented."); return null; } public void Dispose() { AudioSourcePool.RecycleAll(); } } }