//------------------------------------------------------------ // Game Framework // Copyright © 2013-2021 loyalsoft. All rights reserved. // Homepage: http://www.game7000.com/ // Feedback: http://www.game7000.com/ //------------------------------------------------------------ using GameFramework; using GameFramework.Sound; using System; using System.Collections; using UnityEngine; using UnityEngine.Audio; namespace UnityGameFramework.Runtime { /// /// 默认声音代理辅助器。 /// public class DefaultSoundAgentHelper : SoundAgentHelperBase { private Transform m_CachedTransform = null; private AudioSource m_AudioSource = null; private EntityLogic m_BindingEntityLogic = null; private float m_VolumeWhenPause = 0f; private bool m_ApplicationPauseFlag = false; private EventHandler m_ResetSoundAgentEventHandler = null; /// /// 获取当前是否正在播放。 /// public override bool IsPlaying { get { return m_AudioSource.isPlaying; } } /// /// 获取声音长度。 /// public override float Length { get { return m_AudioSource.clip != null ? m_AudioSource.clip.length : 0f; } } /// /// 获取或设置播放位置。 /// public override float Time { get { return m_AudioSource.time; } set { m_AudioSource.time = value; } } /// /// 获取或设置是否静音。 /// public override bool Mute { get { return m_AudioSource.mute; } set { m_AudioSource.mute = value; } } /// /// 获取或设置是否循环播放。 /// public override bool Loop { get { return m_AudioSource.loop; } set { m_AudioSource.loop = value; } } /// /// 获取或设置声音优先级。 /// public override int Priority { get { return 128 - m_AudioSource.priority; } set { m_AudioSource.priority = 128 - value; } } /// /// 获取或设置音量大小。 /// public override float Volume { get { return m_AudioSource.volume; } set { m_AudioSource.volume = value; } } /// /// 获取或设置声音音调。 /// public override float Pitch { get { return m_AudioSource.pitch; } set { m_AudioSource.pitch = value; } } /// /// 获取或设置声音立体声声相。 /// public override float PanStereo { get { return m_AudioSource.panStereo; } set { m_AudioSource.panStereo = value; } } /// /// 获取或设置声音空间混合量。 /// public override float SpatialBlend { get { return m_AudioSource.spatialBlend; } set { m_AudioSource.spatialBlend = value; } } /// /// 获取或设置声音最大距离。 /// public override float MaxDistance { get { return m_AudioSource.maxDistance; } set { m_AudioSource.maxDistance = value; } } /// /// 获取或设置声音多普勒等级。 /// public override float DopplerLevel { get { return m_AudioSource.dopplerLevel; } set { m_AudioSource.dopplerLevel = value; } } /// /// 获取或设置声音代理辅助器所在的混音组。 /// public override AudioMixerGroup AudioMixerGroup { get { return m_AudioSource.outputAudioMixerGroup; } set { m_AudioSource.outputAudioMixerGroup = value; } } /// /// 重置声音代理事件。 /// public override event EventHandler ResetSoundAgent { add { m_ResetSoundAgentEventHandler += value; } remove { m_ResetSoundAgentEventHandler -= value; } } /// /// 播放声音。 /// /// 声音淡入时间,以秒为单位。 public override void Play(float fadeInSeconds) { StopAllCoroutines(); m_AudioSource.Play(); if (fadeInSeconds > 0f) { float volume = m_AudioSource.volume; m_AudioSource.volume = 0f; StartCoroutine(FadeToVolume(m_AudioSource, volume, fadeInSeconds)); } } /// /// 停止播放声音。 /// /// 声音淡出时间,以秒为单位。 public override void Stop(float fadeOutSeconds) { StopAllCoroutines(); if (fadeOutSeconds > 0f && gameObject.activeInHierarchy) { StartCoroutine(StopCo(fadeOutSeconds)); } else { m_AudioSource.Stop(); } } /// /// 暂停播放声音。 /// /// 声音淡出时间,以秒为单位。 public override void Pause(float fadeOutSeconds) { StopAllCoroutines(); m_VolumeWhenPause = m_AudioSource.volume; if (fadeOutSeconds > 0f && gameObject.activeInHierarchy) { StartCoroutine(PauseCo(fadeOutSeconds)); } else { m_AudioSource.Pause(); } } /// /// 恢复播放声音。 /// /// 声音淡入时间,以秒为单位。 public override void Resume(float fadeInSeconds) { StopAllCoroutines(); m_AudioSource.UnPause(); if (fadeInSeconds > 0f) { StartCoroutine(FadeToVolume(m_AudioSource, m_VolumeWhenPause, fadeInSeconds)); } else { m_AudioSource.volume = m_VolumeWhenPause; } } /// /// 重置声音代理辅助器。 /// public override void Reset() { m_CachedTransform.localPosition = Vector3.zero; m_AudioSource.clip = null; m_BindingEntityLogic = null; m_VolumeWhenPause = 0f; } /// /// 设置声音资源。 /// /// 声音资源。 /// 是否设置声音资源成功。 public override bool SetSoundAsset(object soundAsset) { AudioClip audioClip = soundAsset as AudioClip; if (audioClip == null) { return false; } m_AudioSource.clip = audioClip; return true; } /// /// 设置声音绑定的实体。 /// /// 声音绑定的实体。 public override void SetBindingEntity(Entity bindingEntity) { m_BindingEntityLogic = bindingEntity.Logic; if (m_BindingEntityLogic != null) { UpdateAgentPosition(); return; } if (m_ResetSoundAgentEventHandler != null) { ResetSoundAgentEventArgs resetSoundAgentEventArgs = ResetSoundAgentEventArgs.Create(); m_ResetSoundAgentEventHandler(this, resetSoundAgentEventArgs); ReferencePool.Release(resetSoundAgentEventArgs); } } /// /// 设置声音所在的世界坐标。 /// /// 声音所在的世界坐标。 public override void SetWorldPosition(Vector3 worldPosition) { m_CachedTransform.position = worldPosition; } private void Awake() { m_CachedTransform = transform; m_AudioSource = gameObject.GetOrAddComponent(); m_AudioSource.playOnAwake = false; m_AudioSource.rolloffMode = AudioRolloffMode.Custom; } private void Update() { if (!m_ApplicationPauseFlag && !IsPlaying && m_AudioSource.clip != null && m_ResetSoundAgentEventHandler != null) { ResetSoundAgentEventArgs resetSoundAgentEventArgs = ResetSoundAgentEventArgs.Create(); m_ResetSoundAgentEventHandler(this, resetSoundAgentEventArgs); ReferencePool.Release(resetSoundAgentEventArgs); return; } if (m_BindingEntityLogic != null) { UpdateAgentPosition(); } } private void OnApplicationPause(bool pause) { m_ApplicationPauseFlag = pause; } private void UpdateAgentPosition() { if (m_BindingEntityLogic.Available) { m_CachedTransform.position = m_BindingEntityLogic.CachedTransform.position; return; } if (m_ResetSoundAgentEventHandler != null) { ResetSoundAgentEventArgs resetSoundAgentEventArgs = ResetSoundAgentEventArgs.Create(); m_ResetSoundAgentEventHandler(this, resetSoundAgentEventArgs); ReferencePool.Release(resetSoundAgentEventArgs); } } private IEnumerator StopCo(float fadeOutSeconds) { yield return FadeToVolume(m_AudioSource, 0f, fadeOutSeconds); m_AudioSource.Stop(); } private IEnumerator PauseCo(float fadeOutSeconds) { yield return FadeToVolume(m_AudioSource, 0f, fadeOutSeconds); m_AudioSource.Pause(); } private IEnumerator FadeToVolume(AudioSource audioSource, float volume, float duration) { float time = 0f; float originalVolume = audioSource.volume; while (time < duration) { time += UnityEngine.Time.deltaTime; audioSource.volume = Mathf.Lerp(originalVolume, volume, time / duration); yield return new WaitForEndOfFrame(); } audioSource.volume = volume; } } }