Easings.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. using UnityEngine;
  2. public static class Easings
  3. {
  4. private const float PI = Mathf.PI;
  5. private const float HALFPI = Mathf.PI / 2.0f;
  6. /// <summary>
  7. /// Easing Functions enumeration
  8. /// </summary>
  9. public enum Function
  10. {
  11. Linear,
  12. QuadraticEaseIn,
  13. QuadraticEaseOut,
  14. QuadraticEaseInOut,
  15. CubicEaseIn,
  16. CubicEaseOut,
  17. CubicEaseInOut,
  18. QuarticEaseIn,
  19. QuarticEaseOut,
  20. QuarticEaseInOut,
  21. QuinticEaseIn,
  22. QuinticEaseOut,
  23. QuinticEaseInOut,
  24. SineEaseIn,
  25. SineEaseOut,
  26. SineEaseInOut,
  27. CircularEaseIn,
  28. CircularEaseOut,
  29. CircularEaseInOut,
  30. ExponentialEaseIn,
  31. ExponentialEaseOut,
  32. ExponentialEaseInOut,
  33. ElasticEaseIn,
  34. ElasticEaseOut,
  35. ElasticEaseInOut,
  36. BackEaseIn,
  37. BackEaseOut,
  38. BackEaseInOut,
  39. BounceEaseIn,
  40. BounceEaseOut,
  41. BounceEaseInOut
  42. }
  43. public static float Interpolate(ref float currentTime, float duration, float deltaTime, bool reverse = false, Function function = Function.Linear)
  44. {
  45. currentTime = Mathf.Clamp01(currentTime + (deltaTime / duration) * (reverse ? -1 : 1));
  46. return Interpolate(currentTime, function);
  47. }
  48. /// <summary>
  49. /// Interpolate using the specified function.
  50. /// </summary>
  51. public static float Interpolate(float p, Function function)
  52. {
  53. switch(function)
  54. {
  55. default:
  56. case Function.Linear: return Linear(p);
  57. case Function.QuadraticEaseOut: return QuadraticEaseOut(p);
  58. case Function.QuadraticEaseIn: return QuadraticEaseIn(p);
  59. case Function.QuadraticEaseInOut: return QuadraticEaseInOut(p);
  60. case Function.CubicEaseIn: return CubicEaseIn(p);
  61. case Function.CubicEaseOut: return CubicEaseOut(p);
  62. case Function.CubicEaseInOut: return CubicEaseInOut(p);
  63. case Function.QuarticEaseIn: return QuarticEaseIn(p);
  64. case Function.QuarticEaseOut: return QuarticEaseOut(p);
  65. case Function.QuarticEaseInOut: return QuarticEaseInOut(p);
  66. case Function.QuinticEaseIn: return QuinticEaseIn(p);
  67. case Function.QuinticEaseOut: return QuinticEaseOut(p);
  68. case Function.QuinticEaseInOut: return QuinticEaseInOut(p);
  69. case Function.SineEaseIn: return SineEaseIn(p);
  70. case Function.SineEaseOut: return SineEaseOut(p);
  71. case Function.SineEaseInOut: return SineEaseInOut(p);
  72. case Function.CircularEaseIn: return CircularEaseIn(p);
  73. case Function.CircularEaseOut: return CircularEaseOut(p);
  74. case Function.CircularEaseInOut: return CircularEaseInOut(p);
  75. case Function.ExponentialEaseIn: return ExponentialEaseIn(p);
  76. case Function.ExponentialEaseOut: return ExponentialEaseOut(p);
  77. case Function.ExponentialEaseInOut: return ExponentialEaseInOut(p);
  78. case Function.ElasticEaseIn: return ElasticEaseIn(p);
  79. case Function.ElasticEaseOut: return ElasticEaseOut(p);
  80. case Function.ElasticEaseInOut: return ElasticEaseInOut(p);
  81. case Function.BackEaseIn: return BackEaseIn(p);
  82. case Function.BackEaseOut: return BackEaseOut(p);
  83. case Function.BackEaseInOut: return BackEaseInOut(p);
  84. case Function.BounceEaseIn: return BounceEaseIn(p);
  85. case Function.BounceEaseOut: return BounceEaseOut(p);
  86. case Function.BounceEaseInOut: return BounceEaseInOut(p);
  87. }
  88. }
  89. /// <summary>
  90. /// Modeled after the line y = x
  91. /// </summary>
  92. static public float Linear(float p)
  93. {
  94. return p;
  95. }
  96. /// <summary>
  97. /// Modeled after the parabola y = x^2
  98. /// </summary>
  99. static public float QuadraticEaseIn(float p)
  100. {
  101. return p * p;
  102. }
  103. /// <summary>
  104. /// Modeled after the parabola y = -x^2 + 2x
  105. /// </summary>
  106. static public float QuadraticEaseOut(float p)
  107. {
  108. return -(p * (p - 2));
  109. }
  110. /// <summary>
  111. /// Modeled after the piecewise quadratic
  112. /// y = (1/2)((2x)^2) ; [0, 0.5)c
  113. /// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1]
  114. /// </summary>
  115. static public float QuadraticEaseInOut(float p)
  116. {
  117. if(p < 0.5f)
  118. {
  119. return 2 * p * p;
  120. }
  121. else
  122. {
  123. return (-2 * p * p) + (4 * p) - 1;
  124. }
  125. }
  126. /// <summary>
  127. /// Modeled after the cubic y = x^3
  128. /// </summary>
  129. static public float CubicEaseIn(float p)
  130. {
  131. return p * p * p;
  132. }
  133. /// <summary>
  134. /// Modeled after the cubic y = (x - 1)^3 + 1
  135. /// </summary>
  136. static public float CubicEaseOut(float p)
  137. {
  138. float f = (p - 1);
  139. return f * f * f + 1;
  140. }
  141. /// <summary>
  142. /// Modeled after the piecewise cubic
  143. /// y = (1/2)((2x)^3) ; [0, 0.5)
  144. /// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1]
  145. /// </summary>
  146. static public float CubicEaseInOut(float p)
  147. {
  148. if(p < 0.5f)
  149. {
  150. return 4 * p * p * p;
  151. }
  152. else
  153. {
  154. float f = ((2 * p) - 2);
  155. return 0.5f * f * f * f + 1;
  156. }
  157. }
  158. /// <summary>
  159. /// Modeled after the quartic x^4
  160. /// </summary>
  161. static public float QuarticEaseIn(float p)
  162. {
  163. return p * p * p * p;
  164. }
  165. /// <summary>
  166. /// Modeled after the quartic y = 1 - (x - 1)^4
  167. /// </summary>
  168. static public float QuarticEaseOut(float p)
  169. {
  170. float f = (p - 1);
  171. return f * f * f * (1 - p) + 1;
  172. }
  173. /// <summary>
  174. // Modeled after the piecewise quartic
  175. // y = (1/2)((2x)^4) ; [0, 0.5)
  176. // y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1]
  177. /// </summary>
  178. static public float QuarticEaseInOut(float p)
  179. {
  180. if(p < 0.5f)
  181. {
  182. return 8 * p * p * p * p;
  183. }
  184. else
  185. {
  186. float f = (p - 1);
  187. return -8 * f * f * f * f + 1;
  188. }
  189. }
  190. /// <summary>
  191. /// Modeled after the quintic y = x^5
  192. /// </summary>
  193. static public float QuinticEaseIn(float p)
  194. {
  195. return p * p * p * p * p;
  196. }
  197. /// <summary>
  198. /// Modeled after the quintic y = (x - 1)^5 + 1
  199. /// </summary>
  200. static public float QuinticEaseOut(float p)
  201. {
  202. float f = (p - 1);
  203. return f * f * f * f * f + 1;
  204. }
  205. /// <summary>
  206. /// Modeled after the piecewise quintic
  207. /// y = (1/2)((2x)^5) ; [0, 0.5)
  208. /// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1]
  209. /// </summary>
  210. static public float QuinticEaseInOut(float p)
  211. {
  212. if(p < 0.5f)
  213. {
  214. return 16 * p * p * p * p * p;
  215. }
  216. else
  217. {
  218. float f = ((2 * p) - 2);
  219. return 0.5f * f * f * f * f * f + 1;
  220. }
  221. }
  222. /// <summary>
  223. /// Modeled after quarter-cycle of sine wave
  224. /// </summary>
  225. static public float SineEaseIn(float p)
  226. {
  227. return Mathf.Sin((p - 1) * HALFPI) + 1;
  228. }
  229. /// <summary>
  230. /// Modeled after quarter-cycle of sine wave (different phase)
  231. /// </summary>
  232. static public float SineEaseOut(float p)
  233. {
  234. return Mathf.Sin(p * HALFPI);
  235. }
  236. /// <summary>
  237. /// Modeled after half sine wave
  238. /// </summary>
  239. static public float SineEaseInOut(float p)
  240. {
  241. return 0.5f * (1 - Mathf.Cos(p * PI));
  242. }
  243. /// <summary>
  244. /// Modeled after shifted quadrant IV of unit circle
  245. /// </summary>
  246. static public float CircularEaseIn(float p)
  247. {
  248. return 1 - Mathf.Sqrt(1 - (p * p));
  249. }
  250. /// <summary>
  251. /// Modeled after shifted quadrant II of unit circle
  252. /// </summary>
  253. static public float CircularEaseOut(float p)
  254. {
  255. return Mathf.Sqrt((2 - p) * p);
  256. }
  257. /// <summary>
  258. /// Modeled after the piecewise circular function
  259. /// y = (1/2)(1 - Math.Sqrt(1 - 4x^2)) ; [0, 0.5)
  260. /// y = (1/2)(Math.Sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1]
  261. /// </summary>
  262. static public float CircularEaseInOut(float p)
  263. {
  264. if(p < 0.5f)
  265. {
  266. return 0.5f * (1 - Mathf.Sqrt(1 - 4 * (p * p)));
  267. }
  268. else
  269. {
  270. return 0.5f * (Mathf.Sqrt(-((2 * p) - 3) * ((2 * p) - 1)) + 1);
  271. }
  272. }
  273. /// <summary>
  274. /// Modeled after the exponential function y = 2^(10(x - 1))
  275. /// </summary>
  276. static public float ExponentialEaseIn(float p)
  277. {
  278. return (p == 0.0f) ? p : Mathf.Pow(2, 10 * (p - 1));
  279. }
  280. /// <summary>
  281. /// Modeled after the exponential function y = -2^(-10x) + 1
  282. /// </summary>
  283. static public float ExponentialEaseOut(float p)
  284. {
  285. return (p == 1.0f) ? p : 1 - Mathf.Pow(2, -10 * p);
  286. }
  287. /// <summary>
  288. /// Modeled after the piecewise exponential
  289. /// y = (1/2)2^(10(2x - 1)) ; [0,0.5)
  290. /// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1]
  291. /// </summary>
  292. static public float ExponentialEaseInOut(float p)
  293. {
  294. if(p == 0.0 || p == 1.0) return p;
  295. if(p < 0.5f)
  296. {
  297. return 0.5f * Mathf.Pow(2, (20 * p) - 10);
  298. }
  299. else
  300. {
  301. return -0.5f * Mathf.Pow(2, (-20 * p) + 10) + 1;
  302. }
  303. }
  304. /// <summary>
  305. /// Modeled after the damped sine wave y = sin(13pi/2*x)*Math.Pow(2, 10 * (x - 1))
  306. /// </summary>
  307. static public float ElasticEaseIn(float p)
  308. {
  309. return Mathf.Sin(13 * HALFPI * p) * Mathf.Pow(2, 10 * (p - 1));
  310. }
  311. /// <summary>
  312. /// Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*Math.Pow(2, -10x) + 1
  313. /// </summary>
  314. static public float ElasticEaseOut(float p)
  315. {
  316. return Mathf.Sin(-13 * HALFPI * (p + 1)) * Mathf.Pow(2, -10 * p) + 1;
  317. }
  318. /// <summary>
  319. /// Modeled after the piecewise exponentially-damped sine wave:
  320. /// y = (1/2)*sin(13pi/2*(2*x))*Math.Pow(2, 10 * ((2*x) - 1)) ; [0,0.5)
  321. /// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*Math.Pow(2,-10(2*x-1)) + 2) ; [0.5, 1]
  322. /// </summary>
  323. static public float ElasticEaseInOut(float p)
  324. {
  325. if(p < 0.5f)
  326. {
  327. return 0.5f * Mathf.Sin(13 * HALFPI * (2 * p)) * Mathf.Pow(2, 10 * ((2 * p) - 1));
  328. }
  329. else
  330. {
  331. return 0.5f * (Mathf.Sin(-13 * HALFPI * ((2 * p - 1) + 1)) * Mathf.Pow(2, -10 * (2 * p - 1)) + 2);
  332. }
  333. }
  334. /// <summary>
  335. /// Modeled after the overshooting cubic y = x^3-x*sin(x*pi)
  336. /// </summary>
  337. static public float BackEaseIn(float p)
  338. {
  339. return p * p * p - p * Mathf.Sin(p * PI);
  340. }
  341. /// <summary>
  342. /// Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi))
  343. /// </summary>
  344. static public float BackEaseOut(float p)
  345. {
  346. float f = (1 - p);
  347. return 1 - (f * f * f - f * Mathf.Sin(f * PI));
  348. }
  349. /// <summary>
  350. /// Modeled after the piecewise overshooting cubic function:
  351. /// y = (1/2)*((2x)^3-(2x)*sin(2*x*pi)) ; [0, 0.5)
  352. /// y = (1/2)*(1-((1-x)^3-(1-x)*sin((1-x)*pi))+1) ; [0.5, 1]
  353. /// </summary>
  354. static public float BackEaseInOut(float p)
  355. {
  356. if(p < 0.5f)
  357. {
  358. float f = 2 * p;
  359. return 0.5f * (f * f * f - f * Mathf.Sin(f * PI));
  360. }
  361. else
  362. {
  363. float f = (1 - (2*p - 1));
  364. return 0.5f * (1 - (f * f * f - f * Mathf.Sin(f * PI))) + 0.5f;
  365. }
  366. }
  367. /// <summary>
  368. /// </summary>
  369. static public float BounceEaseIn(float p)
  370. {
  371. return 1 - BounceEaseOut(1 - p);
  372. }
  373. /// <summary>
  374. /// </summary>
  375. static public float BounceEaseOut(float p)
  376. {
  377. if(p < 4/11.0f)
  378. {
  379. return (121 * p * p)/16.0f;
  380. }
  381. else if(p < 8/11.0f)
  382. {
  383. return (363/40.0f * p * p) - (99/10.0f * p) + 17/5.0f;
  384. }
  385. else if(p < 9/10.0f)
  386. {
  387. return (4356/361.0f * p * p) - (35442/1805.0f * p) + 16061/1805.0f;
  388. }
  389. else
  390. {
  391. return (54/5.0f * p * p) - (513/25.0f * p) + 268/25.0f;
  392. }
  393. }
  394. /// <summary>
  395. /// </summary>
  396. static public float BounceEaseInOut(float p)
  397. {
  398. if(p < 0.5f)
  399. {
  400. return 0.5f * BounceEaseIn(p*2);
  401. }
  402. else
  403. {
  404. return 0.5f * BounceEaseOut(p * 2 - 1) + 0.5f;
  405. }
  406. }
  407. }