diff --git a/Assets/04.AudioCore/RunTime/Abstract/IAudio.cs b/Assets/04.AudioCore/RunTime/Abstract/IAudio.cs index 09aac42..fa87ad6 100644 --- a/Assets/04.AudioCore/RunTime/Abstract/IAudio.cs +++ b/Assets/04.AudioCore/RunTime/Abstract/IAudio.cs @@ -84,9 +84,10 @@ namespace Stary.Evo.AudioCore UniTask FadeInMusic(AudioSource source, float fadeDuration); UniTask FadeOutMusic(AudioSource source, float fadeDuration); - void Stop(); void StopAll(); + + AudioSource GetAudioSource(); } public abstract class AbstractAudio : IAudio @@ -99,6 +100,13 @@ namespace Stary.Evo.AudioCore public abstract UniTask PlayAsync(AudioData audioData); public abstract void StopAll(); + public abstract AudioSource GetAudioSource(); + + + public virtual UniTask FadeOutVoice(float fadeDuration) + { + return UniTask.CompletedTask; + } public virtual void Stop() @@ -114,6 +122,7 @@ namespace Stary.Evo.AudioCore AudioSourcePool.Creation(); } } + /// /// 音频数据初始化 /// @@ -126,11 +135,15 @@ namespace Stary.Evo.AudioCore audioData.volume = 1f; } - if (audioData.fadeDuration == 0) + if (!GetType().Name.Contains("Voice")) { - audioData.fadeDuration = 1f; + if (audioData.fadeDuration == 0) + { + audioData.fadeDuration = 1f; + } } + return audioData; } @@ -181,9 +194,10 @@ namespace Stary.Evo.AudioCore /// /// /// - public async UniTask PlayAudioAWait(AudioSourceToken audioSourceToken, float delay, System.Action onComplete) + public async UniTask PlayAudioAWait(AudioSourceToken audioSourceToken, float delay, + System.Action onComplete, float fadeDuration = 1f) { - await PlayAudioAWait(audioSourceToken, delay); + await PlayAudioAWait(audioSourceToken, delay, fadeDuration); onComplete?.Invoke(); } @@ -194,14 +208,14 @@ namespace Stary.Evo.AudioCore /// /// /// - public async UniTask PlayAudioAWait(AudioSourceToken audioSourceToken, float delay) + public async UniTask PlayAudioAWait(AudioSourceToken audioSourceToken, float delay, float fadeDuration = 1f) { Debug.Log($"PlayAudioAWait:{GetType().Name}"); - if (!GetType().Name.Contains("Voice")) + if (GetType().Name.Contains("Voice")) { - await UniTask.Delay(TimeSpan.FromSeconds(audioSourceToken.source.clip.length - 2f), + await UniTask.Delay(TimeSpan.FromSeconds(audioSourceToken.source.clip.length - fadeDuration), cancellationToken: audioSourceToken.cancellationToken.Token); - await FadeOutMusic(audioSourceToken.source, 2f); + await FadeOutMusic(audioSourceToken.source, fadeDuration); await UniTask.Delay(TimeSpan.FromSeconds(delay), cancellationToken: audioSourceToken.cancellationToken.Token); } diff --git a/Assets/04.AudioCore/RunTime/Base/AudioSourcePool.cs b/Assets/04.AudioCore/RunTime/Base/AudioSourcePool.cs index ca8f939..84874ae 100644 --- a/Assets/04.AudioCore/RunTime/Base/AudioSourcePool.cs +++ b/Assets/04.AudioCore/RunTime/Base/AudioSourcePool.cs @@ -43,7 +43,7 @@ namespace Stary.Evo.AudioCore public class AudioSourcePool : IAudioSourcePool { - private GameObject poolObject; + private Transform active; /// /// 回收对象的父物体 @@ -70,18 +70,26 @@ namespace Stary.Evo.AudioCore public AudioSourcePool(string poolName, int poolSize) { this.poolSize = poolSize; - poolObject = GameObject.Find(poolName); + var poolObject = GameObject.Find(poolName); if (poolObject == null) { // 如果不存在,创建一个新对象 - poolObject = new GameObject(poolName); + active = new GameObject(poolName).transform; + } + else + { + active = poolObject.transform; } - poolObject = GameObject.Find($"recycle_{poolName}"); - if (poolObject == null) + var recycleObject = GameObject.Find($"recycle_{poolName}"); + if (recycle == null) { // 如果不存在,创建一个新对象 - poolObject = new GameObject($"recycle_{poolName}"); + recycle = new GameObject($"recycle_{poolName}").transform; + } + else + { + recycle = recycleObject.transform; } } @@ -94,7 +102,7 @@ namespace Stary.Evo.AudioCore AudioSource source = CreatAudioSource(); if (source == null) { - Debug.LogErrorFormat("对象池【{0}】已达最大数量【{1}】,无法创建新对象", poolObject.name, poolSize); + Debug.LogErrorFormat("对象池【{0}】已达最大数量【{1}】,无法创建新对象", active.name, poolSize); return; } @@ -118,7 +126,7 @@ namespace Stary.Evo.AudioCore if (noRecycleCount > 0) { audioSourceToken = inactivepool.Dequeue(); - audioSourceToken.source.transform.SetParent(poolObject.gameObject.transform); + audioSourceToken.source.transform.parent = active; noRecycleCount--; if (audioSourceToken.source == null) Debug.LogErrorFormat("对象池中不存在此对象【{0}】请排查代码", audioSourceToken.source); @@ -129,7 +137,7 @@ namespace Stary.Evo.AudioCore var source = CreatAudioSource(); if (source == null) { - Debug.LogErrorFormat("对象池【{0}】已达最大数量【{1}】,无法创建新对象", poolObject.name, poolSize); + Debug.LogErrorFormat("对象池【{0}】已达最大数量【{1}】,无法创建新对象", active.name, poolSize); return null; } @@ -184,7 +192,7 @@ namespace Stary.Evo.AudioCore { noRecycleCount = 0; poolCount = 0; - GameObject.Destroy(poolObject); + GameObject.Destroy(active.gameObject); inactivepool.Clear(); GameObject.Destroy(recycle.gameObject); for (int i = 0; i < activepool.Count; i++) @@ -204,9 +212,9 @@ namespace Stary.Evo.AudioCore if (poolCount >= poolSize && poolSize > 0) return null; poolCount++; - AudioSource source = new GameObject($"{poolObject.name}_{poolCount}").AddComponent(); + AudioSource source = new GameObject($"{active.name}_{poolCount}").AddComponent(); source.gameObject.transform.SetParent(recycle); - source.transform.SetParent(poolObject.transform); // 将新对象作为当前对象的子对象 + source.transform.SetParent(active.transform); // 将新对象作为当前对象的子对象 source.playOnAwake = false; // 添加 AudioSource 组件并禁用自动播放 return source; } @@ -228,6 +236,12 @@ namespace Stary.Evo.AudioCore this.cancellationToken = cancellationToken; } + public AudioSourceToken(AudioSourceToken sourceToken) + { + this.source = sourceToken.source; + this.cancellationToken = sourceToken.cancellationToken; + } + // 添加释放方法 public void Dispose() { diff --git a/Assets/04.AudioCore/RunTime/Base/MusicPlayer.cs b/Assets/04.AudioCore/RunTime/Base/MusicPlayer.cs index 9dd1f55..a899ac6 100644 --- a/Assets/04.AudioCore/RunTime/Base/MusicPlayer.cs +++ b/Assets/04.AudioCore/RunTime/Base/MusicPlayer.cs @@ -145,6 +145,11 @@ namespace Stary.Evo.AudioCore FadeAllMusic(); } + public override AudioSource GetAudioSource() + { + return currentAudioSource; + } + /// /// 关闭背景音乐 /// diff --git a/Assets/04.AudioCore/RunTime/Base/SFXPlayer.cs b/Assets/04.AudioCore/RunTime/Base/SFXPlayer.cs index 9ca32b2..e7b0f19 100644 --- a/Assets/04.AudioCore/RunTime/Base/SFXPlayer.cs +++ b/Assets/04.AudioCore/RunTime/Base/SFXPlayer.cs @@ -22,8 +22,7 @@ namespace Stary.Evo.AudioCore { AudioSourceToken audioSourceToken = await PlayAudio(audioData); // 使用协程处理延迟和回调 - PlayAudioAWait(audioSourceToken, audioData.delayOnCompleteTime, - audioData.onComplete); + PlayAudioAWait(audioSourceToken, audioData.delayOnCompleteTime, audioData.onComplete); } public override async UniTask PlayAsync(AudioData audioData) @@ -113,6 +112,12 @@ namespace Stary.Evo.AudioCore AudioSourcePool.RecycleAll(); } + public override AudioSource GetAudioSource() + { + Debug.LogWarning("SFXPlayer: GetAudioSource is not implemented."); + return null; + } + public void Dispose() { AudioSourcePool.RecycleAll(); diff --git a/Assets/04.AudioCore/RunTime/Base/VoicePlayer.cs b/Assets/04.AudioCore/RunTime/Base/VoicePlayer.cs index 16c0da8..27badb9 100644 --- a/Assets/04.AudioCore/RunTime/Base/VoicePlayer.cs +++ b/Assets/04.AudioCore/RunTime/Base/VoicePlayer.cs @@ -27,7 +27,7 @@ namespace Stary.Evo.AudioCore AudioSourceToken audioSourceToken = await PlayAudio(audioData); // 使用协程处理延迟和回调 PlayAudioAWait(audioSourceToken, - audioData.delayOnCompleteTime, audioData.onComplete); + audioData.delayOnCompleteTime, audioData.onComplete, audioData.fadeDuration); } /// @@ -41,7 +41,7 @@ namespace Stary.Evo.AudioCore public override async UniTask PlayAsync(AudioData audioData) { AudioSourceToken audioSourceToken = await PlayAudio(audioData); - await PlayAudioAWait(audioSourceToken, audioData.delayOnCompleteTime); + await PlayAudioAWait(audioSourceToken, audioData.delayOnCompleteTime, audioData.fadeDuration); } @@ -113,7 +113,7 @@ namespace Stary.Evo.AudioCore } currentSource.source.Play(); - + FadeInMusic(currentSource.source, audioData.fadeDuration); return audioSourceToken; } @@ -137,6 +137,11 @@ namespace Stary.Evo.AudioCore AudioSourcePool.RecycleAll(); } + public override AudioSource GetAudioSource() + { + return currentSource.source; + } + public void Dispose() { AudioSourcePool.RecycleAll(); diff --git a/Assets/04.AudioCore/RunTime/Use/AudioCoreManager.cs b/Assets/04.AudioCore/RunTime/Use/AudioCoreManager.cs index 4118990..10feaa4 100644 --- a/Assets/04.AudioCore/RunTime/Use/AudioCoreManager.cs +++ b/Assets/04.AudioCore/RunTime/Use/AudioCoreManager.cs @@ -20,7 +20,6 @@ namespace Stary.Evo.AudioCore Voice = new VoicePlayer(Resources); SFX = new SFXPlayer(Resources); Music = new MusicPlayer(Resources); - } #region 语音 @@ -39,6 +38,7 @@ namespace Stary.Evo.AudioCore Debug.LogError("AudioCoreManager: Voice is null, please initialize it first."); return; } + Voice?.Play(audioData); } @@ -58,6 +58,7 @@ namespace Stary.Evo.AudioCore Debug.LogError("AudioCoreManager: Voice is null, please initialize it first."); return UniTask.CompletedTask; } + return Voice.PlayAsync(audioData); } @@ -71,6 +72,20 @@ namespace Stary.Evo.AudioCore Debug.LogError("AudioCoreManager: Voice is null, please initialize it first."); return; } + + Voice.Stop(); + } + + /// + /// 停止当前的语音 + /// + public static async UniTask FadeOutVoice(float fadeDuration) + { + if (Voice == null) + { + Debug.LogError("AudioCoreManager: Voice is null, please initialize it first."); + } + await Voice.FadeOutMusic(Voice.GetAudioSource(), fadeDuration); Voice.Stop(); } @@ -92,6 +107,7 @@ namespace Stary.Evo.AudioCore Debug.LogError("AudioCoreManager: SFX is null, please initialize it first."); return; } + SFX.Play(audioData); } @@ -105,6 +121,7 @@ namespace Stary.Evo.AudioCore Debug.LogError("AudioCoreManager: SFX is null, please initialize it first."); return; } + AudioData audioData = new AudioData(); SFX.Stop(); } @@ -126,6 +143,7 @@ namespace Stary.Evo.AudioCore Debug.LogError("AudioCoreManager: Music is null, please initialize it first."); return; } + Music.Play(audioData); } @@ -142,6 +160,7 @@ namespace Stary.Evo.AudioCore Debug.LogError("AudioCoreManager: Music is null, please initialize it first."); return; } + Music.SetMusicVolume(fadeDuration, targetVolume); } @@ -157,6 +176,7 @@ namespace Stary.Evo.AudioCore Debug.LogError("AudioCoreManager: Music is null, please initialize it first."); return; } + Music.Stop(); } diff --git a/Assets/04.AudioCore/package.json b/Assets/04.AudioCore/package.json index 2e6f031..a19bfa4 100644 --- a/Assets/04.AudioCore/package.json +++ b/Assets/04.AudioCore/package.json @@ -1,6 +1,6 @@ { "name": "com.staryevo.audiocore", - "version": "1.1.0", + "version": "1.1.1", "displayName": "04.AudioCore", "description": "音频播放工具", "unity": "2021.3",