//------------------------------------------------------------
// 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;
}
}
}