Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Kurukshetran/011a4130c84e3ccf503a to your computer and use it in GitHub Desktop.
Save Kurukshetran/011a4130c84e3ccf503a to your computer and use it in GitHub Desktop.
PingPongTransformAnimation
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