Skip to content

Instantly share code, notes, and snippets.

@keiranlovett
Created June 13, 2017 03:00
Show Gist options
  • Save keiranlovett/84a76abb5d49292eb9f8740175d62a4a to your computer and use it in GitHub Desktop.
Save keiranlovett/84a76abb5d49292eb9f8740175d62a4a to your computer and use it in GitHub Desktop.
UIBehaviorKit by slonermike
/************************************************************
*
* UI Fade Away
* 2016 Slonersoft Games
*
* Place this on a MaskableGraphic such as Image or Text and
* call Fade to make it fade away and grow.
*
* NOTE: Growth will happen relative to the pivot point of the
* element. This means if your pivot is on the top left, it
* will grow toward the bottom right.
*
************************************************************/
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class UIFadeAway : MonoBehaviour {
[Tooltip("Rate at which to animate.")]
public AnimationCurve curve = AnimationCurve.Linear (0.0f, 0.0f, 1.0f, 1.0f);
[Tooltip("Size to fade away to. 1.0 = no change. 2.0 = double size.")]
public float fadeSize = 2.0f;
[Tooltip("Time over which to perform the fade.")]
public float fadeTime = 1.0f;
[Tooltip("True to fade immediately on load, false to wait for script intervention.")]
public bool fadeImmediately = true;
float progressPct = 0.0f;
MaskableGraphic text;
Vector3 baseScale;
// Use this for initialization
void Start()
{
Initialize();
if (!fadeImmediately) {
Restore ();
}
}
// Grab initial conditions for the graphic.
//
void Initialize()
{
if (text == null)
{
text = GetComponent<MaskableGraphic>();
Fade(fadeTime);
baseScale = text.rectTransform.localScale;
}
}
// Update is called once per frame
void Update()
{
if (progressPct < 1.0f)
{
progressPct = Mathf.Clamp01(progressPct + (Time.deltaTime / fadeTime));
float adjustedPct = curve.Evaluate(progressPct);
text.rectTransform.localScale = Vector3.Lerp(baseScale, baseScale * fadeSize, adjustedPct);
text.color = new Color(text.color.r, text.color.g, text.color.b, 1.0f - adjustedPct);
}
}
// Fade away.
//
// time: time in seconds to perform the fade.
//
public void Fade(float time = -1f)
{
Initialize();
if (fadeTime > 0f)
fadeTime = time;
else
fadeTime = 0.5f;
progressPct = 0.0f;
text.color = new Color(text.color.r, text.color.g, text.color.b, 0.0f);
}
// Restore the graphic to its initial size and full opacity.
//
public void Restore()
{
Initialize();
progressPct = 1.0f;
text.rectTransform.localScale = baseScale;
text.color = new Color(text.color.r, text.color.g, text.color.b, 1.0f);
}
}
/************************************************************
*
* Group Fader
* 2016 Slonersoft Games
*
* Used to fade an entire group of UI elements together.
* All children of this object will be affected.
*
************************************************************/
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class UIGroupFader : MonoBehaviour {
private MaskableGraphic[] elements;
private float currentOpacity;
[Tooltip("How quickly to perform the fade.")]
public float changeRate = 1.0f;
[Tooltip("Time (sec) after which the fade should begin.")]
public float changeDelay = 0.0f;
[Tooltip("Starting opacity level.")]
public float startOpacity = 0.0f;
[Tooltip("Opacity level to fade to.")]
public float goalOpacity = 1.0f;
// Advances a value at a specified speed, stopping it once it reaches that value.
//
// val: current value
// goal: goal value
// speed: rate at which to move toward goal.
//
private float AdvanceValue( float val, float goal, float speed) {
if (val < goal) {
val += speed * Time.deltaTime;
val = val > goal ? goal : val;
} else if (val > goal) {
val -= speed * Time.deltaTime;
val = val < goal ? goal : val;
}
return val;
}
void Awake()
{
elements = gameObject.GetComponentsInChildren<MaskableGraphic> ();
// If I have my own element, add that too.
MaskableGraphic myElem = gameObject.GetComponent<MaskableGraphic> ();
if (myElem) {
MaskableGraphic[] newList = new MaskableGraphic[elements.Length + 1];
for (int i = 0; i < elements.Length; i++) {
newList [i] = elements [i];
}
newList [newList.Length - 1] = myElem;
elements = newList;
}
SetFade (startOpacity);
}
void Update()
{
if (changeDelay <= 0.0f) {
if (currentOpacity != goalOpacity) {
float newOpacity = AdvanceValue (currentOpacity, goalOpacity, changeRate);
SetFade (newOpacity);
}
} else {
changeDelay -= Time.deltaTime;
}
}
// Set the fade amount on all elements in children.
//
void SetFade(float opacity = 1.0f)
{
currentOpacity = opacity;
foreach (MaskableGraphic mg in elements) {
mg.color = new Color(mg.color.r, mg.color.g, mg.color.b, currentOpacity);
}
}
// Start a new fade.
//
// opacity: opacity level to fade to.
// timeSec: time in seconds over which to perform the fade.
// delay (optional): time to wait before performing the fade.
//
public void Fade(float opacity, float timeSec = 0.0f, float delay = 0.0f)
{
goalOpacity = opacity;
changeDelay = delay;
if (timeSec <= 0.0f) {
SetFade (goalOpacity);
} else {
changeRate = 1.0f / timeSec;
}
}
}
************************************************************
*
* UI Pulse
* 2016 Slonersoft Games
*
* Place this on a maskable UI element such as Image or Text
* and it will pulse through the colors laid out in colorPattern.
*
************************************************************/
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class UIPulse : MonoBehaviour {
public Gradient colorPattern; // Pattern for the colors to rotate through.
public float pulseSpeed = 1.0f; // How fast to rotate through the colors.
Color baseColor;
MaskableGraphic image;
bool fwd;
float pct;
// Use this for initialization
void Start () {
image = gameObject.GetComponent<MaskableGraphic> ();
image.color = colorPattern.Evaluate (0.0f);
pct = 0.0f;
fwd = true;
}
// Update is called once per frame
void Update () {
if (fwd) {
pct += pulseSpeed * Time.deltaTime;
} else {
pct -= pulseSpeed * Time.deltaTime;
}
if (pct < 0.0f || pct > 1.0f) {
fwd = !fwd;
pct = Mathf.Clamp01 (pct);
}
image.color = colorPattern.Evaluate (pct);
}
}
/************************************************************
*
* UI Shaker
* 2016 Slonersoft Games
*
* Place this on a UI element and shake it all around by calling
* Shake on this component.
*
************************************************************/
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
public class UIShaker : MonoBehaviour {
float maxMagnitude = 0.0f;
float timeLeft_s = 0.0f;
float timeTotal_s = 0.0f;
RectTransform rectTransform;
Vector3 rootPos;
// Initialize the component, grabbing initial conditions.
//
void Initialize()
{
if (rectTransform == null) {
rectTransform = GetComponent<RectTransform> ();
rootPos = rectTransform.localPosition;
}
}
// Called every frame.
//
void Update () {
if (rectTransform && timeLeft_s > 0) {
// Subtract time until it reaches zero, then the shake is done. Reset the system.
timeLeft_s -= Time.deltaTime;
if (timeLeft_s <= 0.0f) {
timeLeft_s = 0.0f;
timeTotal_s = 0.0f;
}
// Set the local position to the shaken offset.
rectTransform.localPosition = rootPos + GetOffset ();
}
}
// Generates a random offset based on the current state of the shake.
//
Vector3 GetOffset()
{
// Default offset is zero -- no shake.
Vector3 offset = Vector2.zero;
// If there is a current shake in play.
if (timeLeft_s > 0f && timeTotal_s > 0f) {
// Choose a random direction.
float direction = Random.Range (0.0f, 360.0f);
// Create a vector (relative to orientation) with a random direction rotated around the forward axis.
offset = Quaternion.AngleAxis (direction, Vector3.forward) * Vector3.right;
// Determine the current effective spread (between 0 and maxSpread) and multiply the offset by that.
offset *= Mathf.Lerp (0.0f, maxMagnitude, timeLeft_s / timeTotal_s);
}
return offset;
}
// Shake the element!
//
// time_s: Time (in seconds) for the shake to take.
// magnitude: distance (in game units) for the shake to move the camera at its most extreme.
//
public void Shake(float time_s, float magnitude)
{
Initialize ();
timeTotal_s = time_s;
timeLeft_s = time_s;
maxMagnitude = magnitude;
}
}
/************************************************************
*
* UI Slam-In
* 2016 Slonersoft Games
*
* Place this on a UI element such as Image or Text and you
* can call "Slam" on it to have the text slam into place.
*
************************************************************/
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class UISlamIn : MonoBehaviour {
[Tooltip("Determines how slam animates in.")]
public AnimationCurve curve = AnimationCurve.Linear(0.0f, 0.0f, 1.0f, 1.0f);
[Tooltip("How big should it slam in? (1.0 for no size change)")]
public float slamSize = 2.0f;
[Tooltip("Time (sec) for the slam to take.")]
public float slamTime = 1.0f;
[Tooltip("True to slam upon enable, false to wait for script intervention.")]
public bool slamImmediately = false;
float progressPct = 0.0f;
MaskableGraphic graphic;
RectTransform rectTransform;
Vector3 baseScale;
// Use this for initialization
void Start () {
graphic = GetComponent<MaskableGraphic> ();
rectTransform = GetComponent<RectTransform> ();
baseScale = rectTransform.localScale;
Slam (slamTime);
}
// Update is called once per frame
void Update () {
if (progressPct < 1.0f) {
progressPct = Mathf.Clamp01(progressPct + (Time.deltaTime / slamTime));
float adjustedPct = curve.Evaluate (progressPct);
rectTransform.localScale = baseScale * Mathf.Lerp (slamSize, 1f, adjustedPct);
if (graphic != null) {
graphic.color = new Color (graphic.color.r, graphic.color.g, graphic.color.b, adjustedPct);
}
}
}
// Slam the UI text into place.
//
// time (optional): how long should the slam take? Omit to use value set in the inspector.
public void Slam(float time = -1f)
{
if (time > 0f)
slamTime = time;
progressPct = 0.0f;
// Might not be initialized yet.
if (graphic != null) {
graphic.color = new Color (graphic.color.r, graphic.color.g, graphic.color.b, 0.0f);
}
}
}
/************************************************************
*
* UI Value Animator
* 2016 Slonersoft Games
*
* Place this on a Text element and call AnimateValue to change
* the value over time, "tallying" the result.
*
************************************************************/
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class UIValueAnimator : MonoBehaviour {
float animateTime = 1.0f;
float finishTime = -1.0f;
AnimationCurve curve = null;
Text _element = null;
Text element {
get {
if (_element == null) {
_element = GetComponent<Text> ();
if (_element == null) {
Debug.LogError ("Could not find Text element on UIValueAnimator.");
}
}
return _element;
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (finishTime > 0) {
if (Time.time < finishTime) {
SetValue(Mathf.FloorToInt (curve.Evaluate (Time.time)));
} else {
SetValue (Mathf.FloorToInt (curve.Evaluate (finishTime)));
curve = null;
finishTime = -1f;
}
}
}
int GetCurrentValue()
{
int result = 0;
int.TryParse (element.text, out result);
return result;
}
// Set the value of the text immediately without animating.
//
// value: new value for the element.
//
public void SetValue(int value)
{
element.text = "" + value;
}
// Animate toward a new value.
//
// endVal: new value to animate toward.
// animTime (optional): time to take getting to endVal. Omit to use value set in inspector.
//
public void AnimateValue(int endVal, float animTime = -1.0f)
{
if (animTime > 0) {
animateTime = animTime;
}
finishTime = Time.time + animateTime;
curve = AnimationCurve.EaseInOut (Time.time, GetCurrentValue(), finishTime, endVal);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment