Skip to content

Instantly share code, notes, and snippets.

@EddieCameron
Last active August 29, 2015 14:14
Show Gist options
  • Save EddieCameron/5abc0286d5d87865a986 to your computer and use it in GitHub Desktop.
Save EddieCameron/5abc0286d5d87865a986 to your computer and use it in GitHub Desktop.
/* SmoothSwitcher.cs
* Copyright Eddie Cameron 2015
* ----------------------------
* When you want some value to switch slowly between on and off without all that fuss about whether it's already changing or whatnot
* (eg: light dimmer switch, audio fade in/out, zoom)
* -----------------------------
* Can be added to an object at runtime, with SmoothSwitcher.SetupSmoothSwitcher(...)
* Otherwise, make sure to set the SmoothSwitcher's onAmountSet event in the inspector, which will be called whenever the 'on amount' changes
* (when setting an event listener method, make sure to choose a 'dynamic' method in the selection menu, otherwise it'll just call whatever number is in the box)
* -----------------------------
* eg use, for a light dimmer that starts turned off:
*
* public class LightDimmer : MonoBehaviour {
* public float dimTime = 2f;
* public float onLightIntensity = 2f;
*
* SmoothSwitcher mySwitch;
*
* void Start() {
* mySwitch = SmoothSwitcher.SetupSmoothSwitcher( this, dimTime, false, OnDimSet );
* }
*
* public void SwitchOn() {
* mySwitch.SwitchOn();
* }
*
* //... likewise for SwitchOff and Toggle, or can access switch directly, of course
*
* void OnDimSet( float dimAmount ) {
* light.intensity = dimAmount * onLightIntensity;
* }
* }
*/
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using System.Collections.Generic;
public class SmoothSwitcher : MonoBehaviour {
public float switchTime;
[System.Serializable]
public class SwitchAmountSetEvent : UnityEvent<float> { }
public SwitchAmountSetEvent onAmountSet = new SwitchAmountSetEvent();
public bool isOn { get; private set; }
float _onAmount;
public float onAmount {
get { return _onAmount; }
private set {
_onAmount = value;
onAmountSet.Invoke( value );
}
}
float switchAmount;
bool isSwitching;
void Start() {
switchAmount = onAmount = isOn ? 1 : 0;
}
void Init( float switchTime, bool startOn, UnityAction<float> onSetOnAmountAction ) {
this.switchTime = switchTime;
onAmountSet.AddListener( onSetOnAmountAction );
isOn = startOn;
}
void Update() {
if ( isSwitching ) {
if ( isOn ) {
// switching off
switchAmount -= Time.deltaTime / switchTime;
if ( switchAmount > 0f )
onAmount = switchAmount;
else {
// done switch
switchAmount = 0f;
isSwitching = false;
isOn = false;
onAmount = 0f;
}
}
else {
// switching on
switchAmount += Time.deltaTime / switchTime;
if ( switchAmount < 1f )
onAmount = switchAmount;
else {
// done switch
switchAmount = 1f;
isSwitching = false;
isOn = true;
onAmount = 1f;
}
}
}
}
public void SwitchOn() {
if ( isSwitching ) {
if ( isOn ) {
// currently switching off. Reverse
isOn = false;
}
}
else if ( !isOn ) {
// switch on
isSwitching = true;
}
}
public void SwitchOff() {
if ( isSwitching ) {
if ( !isOn ) {
// currently switching on. Reverse
isOn = true;
}
}
else if ( isOn ) {
// switch off
isSwitching = true;
}
}
public void Toggle() {
if ( isSwitching )
isOn = !isOn; // reverse current switching
else
isSwitching = true; // start new switch
}
#region Auto setup
public static SmoothSwitcher SetupSmoothSwitcher( Component onComponent, float switchTime, bool startOn, UnityAction<float> onSetOnAmountAction ) {
return SetupSmoothSwitcher( onComponent.gameObject, switchTime, startOn, onSetOnAmountAction );
}
public static SmoothSwitcher SetupSmoothSwitcher( GameObject onObj, float switchTime, bool startOn, UnityAction<float> onSetOnAmountAction ) {
var newSwitcher = onObj.AddComponent<SmoothSwitcher>();
newSwitcher.Init( switchTime, startOn, onSetOnAmountAction );
return newSwitcher;
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment