SRMath.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System;
  2. using UnityEngine;
  3. public static partial class SRMath
  4. {
  5. /// <summary>
  6. /// Lerp from one value to another, without clamping t to 0-1.
  7. /// </summary>
  8. /// <param name="from"></param>
  9. /// <param name="to"></param>
  10. /// <param name="t"></param>
  11. /// <returns></returns>
  12. public static float LerpUnclamped(float from, float to, float t)
  13. {
  14. return (1.0f - t)*from + t*to;
  15. }
  16. /// <summary>
  17. /// Lerp from one vector to another, without clamping t
  18. /// </summary>
  19. /// <param name="from"></param>
  20. /// <param name="to"></param>
  21. /// <param name="t"></param>
  22. /// <returns></returns>
  23. public static Vector3 LerpUnclamped(Vector3 from, Vector3 to, float t)
  24. {
  25. return new Vector3(
  26. LerpUnclamped(from.x, to.x, t),
  27. LerpUnclamped(from.y, to.y, t),
  28. LerpUnclamped(from.z, to.z, t)
  29. );
  30. }
  31. /// <summary>
  32. /// Value from 0.0f-1.0f, 0 when facing fully away and 1.0f when facing fully towards
  33. /// </summary>
  34. public static float FacingNormalized(Vector3 dir1, Vector3 dir2)
  35. {
  36. dir1.Normalize();
  37. dir2.Normalize();
  38. return Mathf.InverseLerp(-1, 1, Vector3.Dot(dir1, dir2));
  39. }
  40. /// <summary>
  41. /// Reduces a given angle to a value between 180 and -180.
  42. /// </summary>
  43. /// <param name="angle">The angle to reduce, in radians.</param>
  44. /// <returns>The new angle, in radians.</returns>
  45. /// https://github.com/mono/MonoGame/blob/develop/MonoGame.Framework/MathHelper.cs
  46. public static float WrapAngle(float angle)
  47. {
  48. if (angle <= -180f)
  49. {
  50. angle += 360f;
  51. }
  52. else
  53. {
  54. if (angle > 180f)
  55. {
  56. angle -= 360f;
  57. }
  58. }
  59. return angle;
  60. }
  61. /// <summary>
  62. /// Return the angle closest to 'to'
  63. /// </summary>
  64. /// <param name="to"></param>
  65. /// <param name="angle1"></param>
  66. /// <param name="angle2"></param>
  67. /// <returns></returns>
  68. public static float NearestAngle(float to, float angle1, float angle2)
  69. {
  70. if (Mathf.Abs(Mathf.DeltaAngle(to, angle1)) > Mathf.Abs(Mathf.DeltaAngle(to, angle2)))
  71. {
  72. return angle2;
  73. }
  74. return angle1;
  75. }
  76. /// <summary>
  77. /// Wrap value to 0-max (non-inclusive)
  78. /// </summary>
  79. /// <param name="max">Max value (non-inclusive)</param>
  80. /// <param name="value"></param>
  81. /// <returns>Value wrapped from 0-max</returns>
  82. public static int Wrap(int max, int value)
  83. {
  84. if (max < 0)
  85. {
  86. throw new ArgumentOutOfRangeException("max", "max must be greater than 0");
  87. }
  88. while (value < 0)
  89. {
  90. value += max;
  91. }
  92. while (value >= max)
  93. {
  94. value -= max;
  95. }
  96. return value;
  97. }
  98. /// <summary>
  99. /// Wrap value to 0-max (non-inclusive)
  100. /// </summary>
  101. /// <param name="max">Max value (non-inclusive)</param>
  102. /// <param name="value"></param>
  103. /// <returns>Value wrapped from 0-max</returns>
  104. public static float Wrap(float max, float value)
  105. {
  106. while (value < 0)
  107. {
  108. value += max;
  109. }
  110. while (value >= max)
  111. {
  112. value -= max;
  113. }
  114. return value;
  115. }
  116. public static float Average(float v1, float v2)
  117. {
  118. return (v1 + v2)*0.5f;
  119. }
  120. /// <summary>
  121. /// Return an angle in range -180, 180 based on direction vector
  122. /// </summary>
  123. /// <param name="direction"></param>
  124. /// <returns></returns>
  125. public static float Angle(Vector2 direction)
  126. {
  127. var angle = Vector3.Angle(Vector3.up, direction);
  128. if (Vector3.Cross(direction, Vector3.up).z > 0f)
  129. {
  130. angle *= -1;
  131. }
  132. return angle;
  133. }
  134. }