Forked from jakevsrobots/PingPongTransformAnimation.cs
Created
November 4, 2015 02:52
-
-
Save Kurukshetran/011a4130c84e3ccf503a to your computer and use it in GitHub Desktop.
PingPongTransformAnimation
This file contains hidden or 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; | |
using System.Collections; | |
public class PingPongTransformAnimation : MonoBehaviour | |
{ | |
public enum Easing { None, Hermite, Sinerp, Coserp, Berp, SmoothStep, | |
CircleLerp }; | |
public Easing easing = Easing.None; | |
public Vector3 positionChangePerSecond; | |
public Vector3 rotationChangePerSecond; | |
public Vector3 scaleChangePerSecond; | |
public float duration = 1; | |
Vector3 startPosition; | |
Vector3 endPosition; | |
Quaternion startRotation; | |
Quaternion endRotation; | |
Vector3 startScale; | |
Vector3 endScale; | |
float timer; | |
int direction = 1; | |
void Start() | |
{ | |
startPosition = transform.localPosition; | |
endPosition = startPosition + (positionChangePerSecond * duration); | |
startRotation = transform.localRotation; | |
transform.Rotate(rotationChangePerSecond * duration); | |
endRotation = transform.localRotation; | |
transform.localRotation = startRotation; | |
startScale = transform.localScale; | |
endScale = startScale + (scaleChangePerSecond * duration); | |
} | |
void Update() | |
{ | |
// Update end positions from inspector changes | |
endPosition = startPosition + (positionChangePerSecond * duration); | |
Quaternion storedRotation = transform.localRotation; | |
transform.localRotation = startRotation; | |
transform.Rotate(rotationChangePerSecond * duration); | |
endRotation = transform.localRotation; | |
transform.localRotation = storedRotation; | |
endScale = startScale + (scaleChangePerSecond * duration); | |
// Apply animation | |
if(direction == 1) | |
{ | |
timer = Mathf.MoveTowards(timer, duration, Time.deltaTime); | |
if(timer == duration) | |
direction = -1; | |
} | |
else if(direction == -1) | |
{ | |
timer = Mathf.MoveTowards(timer, 0, Time.deltaTime); | |
if(timer == 0) | |
direction = 1; | |
} | |
float easedTime; | |
if(duration == 0) | |
easedTime = 0; | |
else | |
easedTime = timer/duration; | |
easedTime = ApplyEasing(easedTime); | |
transform.localPosition = Vector3.Lerp(startPosition, endPosition, easedTime); | |
transform.localRotation = Quaternion.Lerp(startRotation, endRotation, easedTime); | |
transform.localScale = Vector3.Lerp(startScale, endScale, easedTime); | |
} | |
float ApplyEasing(float baseValue) | |
{ | |
switch(easing) | |
{ | |
case Easing.None: | |
return baseValue; | |
case Easing.Hermite: | |
return Hermite(0, 1, baseValue); | |
case Easing.Sinerp: | |
return Sinerp(0, 1, baseValue); | |
case Easing.Coserp: | |
return Coserp(0, 1, baseValue); | |
case Easing.Berp: | |
return Berp(0, 1, baseValue); | |
case Easing.SmoothStep: | |
return SmoothStep(0, 1, baseValue); | |
case Easing.CircleLerp: | |
return Clerp(0, 1, baseValue); | |
default: | |
return baseValue; | |
} | |
} | |
// Copied from http://wiki.unity3d.com/index.php?title=Mathfx | |
float Hermite(float start, float end, float value) | |
{ | |
return Mathf.Lerp(start, end, value * value * (3.0f - 2.0f * value)); | |
} | |
float Sinerp(float start, float end, float value) | |
{ | |
return Mathf.Lerp(start, end, Mathf.Sin(value * Mathf.PI * 0.5f)); | |
} | |
float Coserp(float start, float end, float value) | |
{ | |
return Mathf.Lerp(start, end, 1.0f - Mathf.Cos(value * Mathf.PI * 0.5f)); | |
} | |
float Berp(float start, float end, float value) | |
{ | |
value = Mathf.Clamp01(value); | |
value = (Mathf.Sin(value * Mathf.PI * (0.2f + 2.5f * value * value * value)) * Mathf.Pow(1f - value, 2.2f) + value) * (1f + (1.2f * (1f - value))); | |
return start + (end - start) * value; | |
} | |
float SmoothStep (float x, float min, float max) | |
{ | |
x = Mathf.Clamp (x, min, max); | |
float v1 = (x-min)/(max-min); | |
float v2 = (x-min)/(max-min); | |
return -2*v1 * v1 *v1 + 3*v2 * v2; | |
} | |
Vector3 NearestPoint(Vector3 lineStart, Vector3 lineEnd, Vector3 point) | |
{ | |
Vector3 lineDirection = Vector3.Normalize(lineEnd-lineStart); | |
float closestPoint = Vector3.Dot((point-lineStart),lineDirection)/Vector3.Dot(lineDirection,lineDirection); | |
return lineStart+(closestPoint*lineDirection); | |
} | |
Vector3 NearestPointStrict(Vector3 lineStart, Vector3 lineEnd, Vector3 point) | |
{ | |
Vector3 fullDirection = lineEnd-lineStart; | |
Vector3 lineDirection = Vector3.Normalize(fullDirection); | |
float closestPoint = Vector3.Dot((point-lineStart),lineDirection)/Vector3.Dot(lineDirection,lineDirection); | |
return lineStart+(Mathf.Clamp(closestPoint,0.0f,Vector3.Magnitude(fullDirection))*lineDirection); | |
} | |
float Bounce(float x) | |
{ | |
return Mathf.Abs(Mathf.Sin(6.28f*(x+1f)*(x+1f)) * (1f-x)); | |
} | |
// test for value that is near specified float (due to floating point inprecision) | |
// all thanks to Opless for this! | |
bool Approx(float val, float about, float range) | |
{ | |
return ( ( Mathf.Abs(val - about) < range) ); | |
} | |
// test if a Vector3 is close to another Vector3 (due to floating point inprecision) | |
// compares the square of the distance to the square of the range as this | |
// avoids calculating a square root which is much slower than squaring the range | |
bool Approx(Vector3 val, Vector3 about, float range) | |
{ | |
return ( (val - about).sqrMagnitude < range*range); | |
} | |
/* | |
* CLerp - Circular Lerp - is like lerp but handles the wraparound from 0 to 360. | |
* This is useful when interpolating eulerAngles and the object | |
* crosses the 0/360 boundary. The standard Lerp function causes the object | |
* to rotate in the wrong direction and looks stupid. Clerp fixes that. | |
*/ | |
float Clerp(float start , float end, float value) | |
{ | |
float min = 0.0f; | |
float max = 360.0f; | |
float half = Mathf.Abs((max - min)/2.0f);//half the distance between min and max | |
float retval = 0.0f; | |
float diff = 0.0f; | |
if((end - start) < -half){ | |
diff = ((max - start)+end)*value; | |
retval = start+diff; | |
} | |
else if((end - start) > half){ | |
diff = -((max - end)+start)*value; | |
retval = start+diff; | |
} | |
else retval = start+(end-start)*value; | |
// Debug.Log("Start: " + start + " End: " + end + " Value: " + value + " Half: " + half + " Diff: " + diff + " Retval: " + retval); | |
return retval; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment