diff --git a/Assets/04.AudioCore/RunTime/AudioCoreManager.cs b/Assets/04.AudioCore/RunTime/AudioCoreManager.cs index 1ee1197..1bd0ad3 100644 --- a/Assets/04.AudioCore/RunTime/AudioCoreManager.cs +++ b/Assets/04.AudioCore/RunTime/AudioCoreManager.cs @@ -8,7 +8,6 @@ public static class AudioCoreManager private static SFXPlayer SFX; private static MusicPlayer Music; - // 初始化 AudioCoreManager static AudioCoreManager() { audioSourcePool = new AudioSourcePool(); @@ -18,39 +17,98 @@ public static class AudioCoreManager Music = new MusicPlayer(audioSourcePool); } - // 播放语音 + #region 语音 + + /// + /// 播放语音 + /// + /// 音频 + /// 结束行为 + /// 结束行为延迟执行时间 + public static void PlayVoice(AudioClip clip, System.Action onComplete, float delay = 0f) + { + Voice.Play(clip, 1f, onComplete, delay); + } + + /// + /// 播放语音 + /// + /// 音频 + /// 音量 + /// 结束行为 + /// 结束行为延迟执行时间 public static void PlayVoice(AudioClip clip, float volume = 1f, System.Action onComplete = null, float delay = 0f) { Voice.Play(clip, volume, onComplete, delay); } - // 停止语音 + /// + /// 停止当前的语音 + /// public static void StopVoice() { Voice.Stop(); } - // 播放音效 + #endregion + + #region 音效 + + /// + /// 播放音效 + /// + /// 音频 + /// 结束行为 + /// 结束行为延迟执行时间 + public static void PlaySFX(AudioClip clip, System.Action onComplete, float delay = 0f) + { + SFX.Play(clip, 1f, onComplete, delay); + } + + /// + /// 播放音效 + /// + /// 音频 + /// 音量 + /// 结束行为 + /// 结束行为延迟执行时间 public static void PlaySFX(AudioClip clip, float volume = 1f, System.Action onComplete = null, float delay = 0f) { SFX.Play(clip, volume, onComplete, delay); } - // 停止所有音效 + /// + /// 停止所有音效 + /// public static void StopAllSFX() { SFX.Stop(); } - // 播放背景音乐 - public static void PlayMusic(AudioClip clip, float fadeDuration = 0f) + #endregion + + #region 背景音乐 + + /// + /// 播放背景音乐 + /// + /// 音频 + /// 音量 + /// 自然过渡时间 + public static void PlayMusic(AudioClip clip, float volume = 1f, float fadeDuration = 1f) { - Music.Play(clip, fadeDuration); + Music.Play(clip, volume, fadeDuration); } - // 停止背景音乐 + /// + /// 停止播放背景音乐 + /// + /// 自然过渡时间 public static void StopMusic(float fadeDuration = 1f) { Music.Stop(fadeDuration); } + + #endregion + } \ No newline at end of file diff --git a/Assets/04.AudioCore/RunTime/AudioSourcePool.cs b/Assets/04.AudioCore/RunTime/AudioSourcePool.cs index 1ca4932..2a19026 100644 --- a/Assets/04.AudioCore/RunTime/AudioSourcePool.cs +++ b/Assets/04.AudioCore/RunTime/AudioSourcePool.cs @@ -4,7 +4,6 @@ using UnityEngine.SceneManagement; public class AudioSourcePool { - // 对象池字典,存储类型和对应的 GameObject 队列 private Dictionary> poolDict = new Dictionary>(); private GameObject poolObject; @@ -23,7 +22,7 @@ public class AudioSourcePool } CoroutineHelper.SetRunner(); - // 初始化 Voice 池(最多 1 个) + // 初始化 Voice 池(最多 1 个,可动态扩展) poolDict["Voice"] = new Queue(); CreateAudioSource("Voice"); @@ -51,6 +50,10 @@ public class AudioSourcePool GameObject newObject = new GameObject($"AudioSource_{type}"); newObject.transform.SetParent(poolObject.transform); // 将新对象作为当前对象的子对象 newObject.AddComponent().playOnAwake = false; // 添加 AudioSource 组件并禁用自动播放 + if(type == "Music") + { + newObject.GetComponent().loop = true; + } poolDict[type].Enqueue(newObject); } @@ -74,8 +77,8 @@ public class AudioSourcePool if (poolDict[type].Count == 0) { - /*// 如果池为空,动态创建新的 GameObject(仅限 SFX) - if (type == "SFX") + // 如果池为空,动态创建新的 GameObject(仅限 SFX 与 Voice) + if (type == "SFX" && type == "Voice") { CreateAudioSource(type); } @@ -83,7 +86,7 @@ public class AudioSourcePool { Debug.LogWarning($"对象池 {type} 已用完,无法分配新的 AudioSource"); return null; - }*/ + } CreateAudioSource(type); } diff --git a/Assets/04.AudioCore/RunTime/IAudio.cs b/Assets/04.AudioCore/RunTime/IAudio.cs index 6157b57..ee188a8 100644 --- a/Assets/04.AudioCore/RunTime/IAudio.cs +++ b/Assets/04.AudioCore/RunTime/IAudio.cs @@ -4,7 +4,7 @@ using UnityEngine; public interface IAudio { - void Play(AudioClip audioClip,float volume); + void Play(AudioClip audioClip,float volume, System.Action onComplete, float delay); void Stop(); @@ -17,7 +17,7 @@ public interface IAudio } public abstract class AbstractAudio : IAudio { - public abstract void Play(AudioClip audioClip, float volume); + public abstract void Play(AudioClip audioClip, float volume, System.Action onComplete, float delay); public abstract void Stop(); diff --git a/Assets/04.AudioCore/RunTime/MusicPlayer.cs b/Assets/04.AudioCore/RunTime/MusicPlayer.cs index dd47e6d..d8fff31 100644 --- a/Assets/04.AudioCore/RunTime/MusicPlayer.cs +++ b/Assets/04.AudioCore/RunTime/MusicPlayer.cs @@ -4,38 +4,84 @@ using UnityEngine; public class MusicPlayer { private AudioSourcePool audioSourcePool; + private AudioSource audioSource1; + private AudioSource audioSource2; + private AudioSource currentAudioSource; public MusicPlayer(AudioSourcePool audioSourcePool) { this.audioSourcePool = audioSourcePool; } - public void Play(AudioClip clip, float fadeDuration) + /// + /// 播放背景音乐 + /// + /// 音频 + /// 音量 + /// 自然过渡时间 + public void Play(AudioClip clip, float volume, float fadeDuration) { - AudioSource source = audioSourcePool.GetAudioSource("Music"); - if (source == null) return; - - CoroutineHelper.StartCoroutine(FadeMusic(source, clip, fadeDuration)); + if(audioSource1 == null) + { + audioSource1 = audioSourcePool.GetAudioSource("Music"); + audioSource1.clip = clip; + audioSource1.volume = volume; + currentAudioSource = audioSource1; + currentAudioSource.Play(); + CoroutineHelper.StartCoroutine(FadeMusic(audioSource1, fadeDuration, audioSource2)); + } + else + { + if (audioSource2 == null) + { + audioSource2 = audioSourcePool.GetAudioSource("Music"); + audioSource2.clip = clip; + audioSource2.volume = volume; + currentAudioSource = audioSource2; + currentAudioSource.Play(); + CoroutineHelper.StartCoroutine(FadeMusic(audioSource2, fadeDuration, audioSource1)); + } + else + { + Debug.LogWarning("已同时存在两个背景乐在切换"); + } + } + } + /// + /// 关闭背景音乐 + /// + /// 关闭时的自然过渡时间 public void Stop(float fadeDuration) { - AudioSource source = audioSourcePool.GetAudioSource("Music"); - if (source == null) return; - - CoroutineHelper.StartCoroutine(FadeOutMusic(source, fadeDuration)); + CoroutineHelper.StartCoroutine(FadeOutMusic(currentAudioSource, fadeDuration)); } - private IEnumerator FadeMusic(AudioSource source, AudioClip clip, float fadeDuration) + /// + /// 切换音频 + /// + /// 播放的音频 + /// 变化时间 + /// 停止的音频 + /// + private IEnumerator FadeMusic(AudioSource source1, float fadeDuration, AudioSource source2 = null) { - yield return FadeOutMusic(source, fadeDuration); + yield return FadeInMusic(source1, fadeDuration); - source.clip = clip; - source.Play(); - - yield return FadeInMusic(source, fadeDuration); + if(source2 != null) + { + yield return FadeOutMusic(source2, fadeDuration); + } + } + /// + /// 关闭音频的协程 + /// + /// + /// + /// private IEnumerator FadeOutMusic(AudioSource source, float fadeDuration) { float startVolume = source.volume; @@ -47,9 +93,24 @@ public class MusicPlayer } source.Stop(); - source.volume = startVolume; + audioSourcePool.ReturnAudioSource("Music", source.gameObject); + + if(currentAudioSource == audioSource1) + { + audioSource2 = null; + } + else if(currentAudioSource == audioSource2) + { + audioSource1 = null; + } } + /// + /// 开启音频的协程 + /// + /// + /// + /// private IEnumerator FadeInMusic(AudioSource source, float fadeDuration) { float targetVolume = source.volume; diff --git a/Assets/04.AudioCore/RunTime/SFXPlayer.cs b/Assets/04.AudioCore/RunTime/SFXPlayer.cs index 8c7d15f..e599231 100644 --- a/Assets/04.AudioCore/RunTime/SFXPlayer.cs +++ b/Assets/04.AudioCore/RunTime/SFXPlayer.cs @@ -12,21 +12,13 @@ public class SFXPlayer this.audioSourcePool = audioSourcePool; } - /*public override void Play(AudioClip clip, float volume = 1f) - { - AudioSource source = audioSourcePool.GetAudioSource("SFX"); - if (source == null) return; - - source.clip = clip; - source.volume = volume; - source.Play(); - - // 将 AudioSource 加入活动列表 - activeSources.Add(source); - } -*/ - - // 播放音效 + /// + /// 播放音效 + /// + /// 音频 + /// 音量 + /// 结束行为 + /// 延迟结束行为时间 public void Play(AudioClip clip, float volume = 1f, System.Action onComplete = null, float delay = 0f) { AudioSource source = audioSourcePool.GetAudioSource("SFX"); @@ -40,10 +32,12 @@ public class SFXPlayer activeSources.Add(source); // 使用协程处理延迟和回调 - CoroutineHelper.StartCoroutine(PlayCoroutine(source, delay, onComplete)); + CoroutineHelper.StartCoroutine(PlaySFXCoroutine(source, delay, onComplete)); } - // 停止所有音效 + /// + /// 停止所有音效 + /// public void Stop() { foreach (var source in activeSources) @@ -57,8 +51,14 @@ public class SFXPlayer activeSources.Clear(); } - // 播放音效的协程 - private IEnumerator PlayCoroutine(AudioSource source, float delay, System.Action onComplete) + /// + /// 播放音效的协程 + /// + /// + /// + /// + /// + private IEnumerator PlaySFXCoroutine(AudioSource source, float delay, System.Action onComplete) { yield return new WaitForSeconds(source.clip.length + delay); diff --git a/Assets/04.AudioCore/RunTime/Test.cs b/Assets/04.AudioCore/RunTime/Test.cs index 68769bb..d2e496a 100644 --- a/Assets/04.AudioCore/RunTime/Test.cs +++ b/Assets/04.AudioCore/RunTime/Test.cs @@ -12,13 +12,11 @@ public class Test : MonoBehaviour public AudioClip clip31; public AudioClip clip32; - // Start is called before the first frame update void Start() { //AudioCore.PlayerPrefs(); } - // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.A)) diff --git a/Assets/04.AudioCore/RunTime/VoicePlayer.cs b/Assets/04.AudioCore/RunTime/VoicePlayer.cs index c6a483d..452dcb9 100644 --- a/Assets/04.AudioCore/RunTime/VoicePlayer.cs +++ b/Assets/04.AudioCore/RunTime/VoicePlayer.cs @@ -4,29 +4,21 @@ using UnityEngine; public class VoicePlayer { private AudioSourcePool audioSourcePool; - private AudioSource currentSource; // 当前正在播放的 AudioSource - Coroutine myCoroutine; + private AudioSource currentSource; + private Coroutine myCoroutine; public VoicePlayer(AudioSourcePool audioSourcePool) { this.audioSourcePool = audioSourcePool; } - /*public override void Play(AudioClip clip, float volume = 1) - { - // 停止当前正在播放的语音 - Stop(); - - currentSource = audioSourcePool.GetAudioSource("Voice"); - if (currentSource == null) return; - - currentSource.clip = clip; - currentSource.volume = volume; - currentSource.Play(); - } -*/ - - // 播放语音 + /// + /// 播放语音 + /// + /// 音频 + /// 音量 + /// 结束行为 + /// 延迟结束行为时间 public void Play(AudioClip clip, float volume = 1f, System.Action onComplete = null, float delayOnComplete = 0f) { // 停止当前正在播放的语音与旧协程 @@ -47,7 +39,9 @@ public class VoicePlayer myCoroutine = CoroutineHelper.StartCoroutine(PlayVoiceCoroutine(currentSource, delayOnComplete, onComplete)); } - // 停止语音 + /// + /// 停止语音 + /// public void Stop() { if (currentSource != null && currentSource.isPlaying) @@ -58,7 +52,13 @@ public class VoicePlayer } } - // 播放语音的协程 + /// + /// 播放语音的协程 + /// + /// + /// + /// + /// private IEnumerator PlayVoiceCoroutine(AudioSource source, float delayOnComplete, System.Action onComplete) { yield return new WaitForSeconds(source.clip.length+delayOnComplete); diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index a8565fb..2da6faf 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -155,8 +155,8 @@ MonoBehaviour: clip2: {fileID: 8300000, guid: 933538c8c54c7b24e9b1c2e06fc52506, type: 3} clip21: {fileID: 8300000, guid: 6689aaa78797acf4aa733003ddad16b9, type: 3} clip22: {fileID: 8300000, guid: 933538c8c54c7b24e9b1c2e06fc52506, type: 3} - clip31: {fileID: 0} - clip32: {fileID: 0} + clip31: {fileID: 8300000, guid: 6689aaa78797acf4aa733003ddad16b9, type: 3} + clip32: {fileID: 8300000, guid: 933538c8c54c7b24e9b1c2e06fc52506, type: 3} --- !u!4 &265350654 Transform: m_ObjectHideFlags: 0