ParabolicTeleport.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //***********************************************************
  2. // Filename: ParabolicTeleport.cs
  3. // Author: Moritz Kolvenbach, Marco Fendrich
  4. // Last changes: Wednesday, 8th of August 2018
  5. // Content: Class that calculates the parabola to be rendered and used to aim when preparing to teleport
  6. //***********************************************************
  7. using UnityEngine;
  8. /// <summary>
  9. /// Child class of RenderableTeleport doing the actual calculations to aim the teleportation as a parabola
  10. /// </summary>
  11. public class ParabolicTeleport : RenderableTeleport
  12. {
  13. [Header("Parabola Trajectory")]
  14. [Tooltip("Initial velocity of the parabola, in local space.")]
  15. public Vector3 initialVelocity = Vector3.forward * 15f;
  16. [Tooltip("World-space \"acceleration\" of the parabola. This affects the falloff of the curve.")]
  17. public Vector3 acceleration = Vector3.up * -9.8f;
  18. /// <summary>
  19. /// Sample a bunch of points along a parabolic curve until you hit ground. At that point, cut off the parabola
  20. /// </summary>
  21. protected override void UpdateProjectionPoints()
  22. {
  23. // turn velocity to work into the direction of the controller
  24. normalisedVelocity = transform.TransformDirection(initialVelocity);
  25. // delete points from last calculation
  26. projectionPoints.Clear();
  27. // add start point - the controller
  28. projectionPoints.Add(transform.position);
  29. // set point from which second point will be calculated to controller position
  30. Vector3 last = transform.position;
  31. float t = 0; // time for parabola calculation hasn't started yet
  32. // iterate through the maximum number of points being calculated
  33. for (int i = 0; i < pointCount; i++)
  34. {
  35. // increase t so that the next calculated point will have the distance set in editor
  36. t += pointSpacing / CalculateNewVelocity(normalisedVelocity, acceleration, t).magnitude;
  37. // calculate next point of line
  38. Vector3 next = CalculateNewPosition(transform.position, normalisedVelocity, acceleration, t);
  39. Vector3 castHit; // hit point of line if colliding at or before next calculated point
  40. Vector3 norm; // normal of hit point
  41. bool endOnNavmesh; // indicator of whether last point calculated ended on navmesh
  42. // check whether something is being hit
  43. if (navMesh.Linecast(last, next, out endOnNavmesh, out castHit, out norm))
  44. {
  45. // if something is being hit, set last point in list to hit point
  46. projectionPoints.Add(castHit);
  47. // normal of hit point to be used when visualizing the currently selected target
  48. normalisedHitPoint = norm;
  49. // check whether point is on nav mesh and therefore teleportable
  50. pointOnNavMesh = endOnNavmesh;
  51. return;
  52. }
  53. else
  54. {
  55. // no collision, calculate next point
  56. projectionPoints.Add(next);
  57. }
  58. // set currently calculated point as base for the calculation of the new point
  59. last = next;
  60. }
  61. // if nothing is being hit and maximum number of points is reached, show unreachable target in midair with normal going upwards
  62. normalisedHitPoint = Vector3.up;
  63. pointOnNavMesh = false;
  64. }
  65. /// <summary>
  66. /// Parabolic motion equation applied to three dimensions
  67. /// </summary>
  68. /// <param name="p0">Position from which the movement of the current update was started</param>
  69. /// <param name="v0">Velocity with which the parabola is being calculated</param>
  70. /// <param name="a">Acceleration with which the parabola is being calculated</param>
  71. /// <param name="t">Abstract time to be used to update point</param>
  72. /// <returns>Next point of parabola</returns>
  73. protected Vector3 CalculateNewPosition(Vector3 p0, Vector3 v0, Vector3 a, float t)
  74. {
  75. Vector3 ret = new Vector3();
  76. for (int i = 0; i < 3; i++)
  77. // Parabolic motion equation, d = p0 + v0*t + 1/2at^2
  78. ret[i] = p0[i] + v0[i] * t + 0.5F * a[i] * t * t;
  79. return ret;
  80. }
  81. /// <summary>
  82. /// Parabolic motion derivative applied to three dimensions; therefore calculating current speed
  83. /// </summary>
  84. /// <param name="v0">Initial velocity</param>
  85. /// <param name="a">Acceleration</param>
  86. /// <param name="t">Time since start of movement</param>
  87. /// <returns>Current speed</returns>
  88. protected Vector3 CalculateNewVelocity(Vector3 v0, Vector3 a, float t)
  89. {
  90. Vector3 ret = new Vector3();
  91. for (int i = 0; i < 3; i++)
  92. // Derivative of parabolic motion equation (calculation of total velocity)
  93. ret[i] = v0[i] + a[i] * t;
  94. return ret;
  95. }
  96. }