Created
July 25, 2015 17:00
-
-
Save yasuakiohama/feb7f00d8beba0623d4e to your computer and use it in GitHub Desktop.
CustomAudioSource.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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