Skip to content

Instantly share code, notes, and snippets.

@yasuakiohama
Created July 25, 2015 17:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yasuakiohama/feb7f00d8beba0623d4e to your computer and use it in GitHub Desktop.
Save yasuakiohama/feb7f00d8beba0623d4e to your computer and use it in GitHub Desktop.
CustomAudioSource.cs
using UnityEngine;
/// <summary>
/// Audio source that fades between clips instead of playing them immediately.
/// </summary>
[RequireComponent(typeof(AudioSource))]
public class CustomAudioSource : MonoBehaviour
{
#region Fields
/// <summary>
/// Actual audio source.
/// </summary>
private AudioSource audioSource;
/// <summary>
/// The type of the execute.
/// </summary>
private ExecuteType executeType = ExecuteType.Nomal;
/// <summary>
/// Whether the audio source is currently fading, in or out.
/// </summary>
private FadeState fadeState = FadeState.None;
/// <summary>
/// The state of the fade.
/// </summary>
private LowlightState lowlightState = LowlightState.None;
/// <summary>
/// Next clip to fade to.
/// </summary>
private AudioClip nextClip;
/// <summary>
/// Whether to loop the next clip.
/// </summary>
private bool nextClipLoop;
/// <summary>
/// Target volume to fade the next clip to.
/// </summary>
private float nextClipVolume;
/// <summary>
/// Volume change per second when fading.
/// </summary>
private float fadeSpeed = 1f;
/// <summary>
/// Volume to end the previous clip at.
/// </summary>
private float fadeOutThreshold = 0.1f;
/// <summary>
/// The lowlight threshold.
/// </summary>
private float lowlightThreshold = 0.2f;
/// <summary>
/// The lowlight fade speed.
/// </summary>
private float lowlightFadeSpeed = 1.0f;
#endregion
#region Enums
public enum ExecuteType
{
Nomal,
Fade,
}
public enum FadeState
{
None,
FadingOut,
FadingIn
}
public enum LowlightState
{
None,
LowlightOut,
LowlightIn
}
#endregion
#region Public Properties
/// <summary>
/// Current clip of the audio source.
/// </summary>
public AudioClip Clip
{
get
{
return this.audioSource.clip;
}
}
/// <summary>
/// Whether the audio source is currently playing a clip.
/// </summary>
public bool IsPlaying
{
get
{
return this.audioSource.isPlaying;
}
}
/// <summary>
/// Whether the audio source is looping the current clip.
/// </summary>
public bool Loop
{
get
{
return this.audioSource.loop;
}
}
/// <summary>
/// Current volume of the audio source.
/// </summary>
public float Volume
{
get
{
return this.audioSource.volume;
}
}
#endregion
#region Public Methods and Operators
/// <summary>
/// Sets the custom audio clip.
/// </summary>
/// <param name="clip">Clip.</param>
/// <param name="volume">Volume.</param>
/// <param name="loop">If set to <c>true</c> loop.</param>
/// <param name="fadeSpeed">Fade speed.</param>
/// <param name="fadeOutThreshold">Fade out threshold.</param>
public void Load(AudioClip clip, float volume = 1.0f, bool loop = true, float fadeSpeed = 1f,float fadeOutThreshold = 0.1f)
{
if (clip != null && clip != this.audioSource.clip) {
this.nextClip = clip;
}
this.nextClipVolume = volume;
this.nextClipLoop = loop;
this.fadeSpeed = fadeSpeed;
this.fadeOutThreshold = fadeOutThreshold;
}
/// <summary>
/// Play the specified executeType.
/// </summary>
/// <param name="executeType">Execute type.</param>
public void Play(ExecuteType executeType = ExecuteType.Nomal)
{
if (this.audioSource.isPlaying && this.nextClip == this.audioSource.clip) {
//すでに同じ曲が流れているなら流さない
return;
}
this.executeType = executeType;
switch (this.executeType) {
case ExecuteType.Nomal:
this.NomalToNextClip ();
break;
case ExecuteType.Fade:
if (this.IsPlaying) {
this.fadeState = FadeState.FadingOut;//プレイ中ならフェードして切り替え
} else {
this.FadeToNextClip ();
}
break;
}
}
/// <summary>
/// Stop
/// </summary>
/// <param name="executeType">Execute type.</param>
public void Stop(ExecuteType executeType = ExecuteType.Nomal)
{
this.executeType = executeType;
switch (this.executeType) {
case ExecuteType.Nomal:
Init ();
break;
case ExecuteType.Fade:
this.nextClip = null;//Audioデータを消す事でフェードした後音を鳴らさないようにする
if (!this.audioSource.isPlaying) {
this.audioSource.Play ();
}
this.fadeState = FadeState.FadingOut;
break;
}
}
/// <summary>
/// Lowlight this instance.
/// </summary>
public void LowlightIn(float lowlightThreshold = 0.2f, float lowlightFadeSpeed = 1.0f)
{
this.lowlightFadeSpeed = lowlightFadeSpeed;
this.lowlightThreshold = lowlightThreshold;
this.lowlightState = LowlightState.LowlightIn;
}
/// <summary>
/// Lowlight this instance.
/// </summary>
public void LowlightOut()
{
this.lowlightState = LowlightState.LowlightOut;
}
/// <summary>
/// Pause this instance.
/// </summary>
public void Pause()
{
this.audioSource.Pause();
}
#endregion
#region Methods
private void Awake()
{
this.audioSource = this.audio;
Init ();
}
private void Init()
{
lowlightState = LowlightState.None;
this.nextClip = null; //Audioデータを消す事でフェードした後音を鳴らさないようにする
this.fadeState = FadeState.None;
this.audioSource.clip = null;
this.audioSource.volume = 0f;
this.audioSource.Stop ();
this.transform.parent.GetComponent<BGMAudioManager> ().EndFadingOut ();
}
private void FadeToNextClip()
{
if (this.nextClip == null) {
Init ();
return;
}
this.fadeState = FadeState.FadingIn;
this.audioSource.clip = this.nextClip;
this.audioSource.loop = this.nextClipLoop;
this.audioSource.Play();
}
private void NomalToNextClip()
{
if (this.nextClip == null) {
Init ();
return;
}
this.fadeState = FadeState.None;
this.audioSource.clip = this.nextClip;
this.audioSource.loop = this.nextClipLoop;
this.audioSource.volume = this.nextClipVolume;//フェードしない場合は即座に流す
this.audioSource.Play ();
}
private void Update()
{
if (!this.audioSource.isPlaying) {
return;
}
if (UpdateLowlight ()) {
return;
}
if (this.executeType == ExecuteType.Nomal) {
return;
}
UpdateFade ();
}
private bool UpdateLowlight()
{
if (lowlightState == LowlightState.None) {
return false;
}
if (lowlightState == LowlightState.LowlightIn) {
if (this.audioSource.volume > this.lowlightThreshold) {
// Fade out current clip.
this.audioSource.volume -= this.lowlightFadeSpeed * Time.deltaTime;
}
} else if (lowlightState == LowlightState.LowlightOut) {
if (this.audioSource.volume < this.nextClipVolume) {
// Fade in next clip.
this.audioSource.volume += this.lowlightFadeSpeed * Time.deltaTime;
} else {
lowlightState = LowlightState.None;
}
}
return true;
}
private void UpdateFade()
{
if (this.fadeState == FadeState.FadingOut)
{
if (this.audioSource.volume > this.fadeOutThreshold) {
// Fade out current clip.
this.audioSource.volume -= this.fadeSpeed * Time.deltaTime;
} else {
// Start fading in next clip.
this.FadeToNextClip ();
}
}
else if (this.fadeState == FadeState.FadingIn)
{
if (this.audioSource.volume < this.nextClipVolume) {
// Fade in next clip.
this.audioSource.volume += this.fadeSpeed * Time.deltaTime;
} else {
// Stop fading in.
this.fadeState = FadeState.None;
}
}
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment