SFX_LerpMotion.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System;
  2. using UnityEngine;
  3. // ReSharper disable once CheckNamespace
  4. namespace QFX.SFX
  5. {
  6. public class SFX_LerpMotion : SFX_ControlledObject
  7. {
  8. public Transform SelfTransform;
  9. public float Speed = 1f;
  10. public float Turn = 1f;
  11. public bool ChangeRotation;
  12. public bool LookAtTarget;
  13. public bool IsArcMotionEnabled;
  14. public float ArcMotionHeight;
  15. private bool _isLerping;
  16. private float _timeStartedLerping;
  17. private Transform _transform;
  18. public Vector3 LaunchPosition { get; set; }
  19. public Vector3 TargetPosition { get; set; }
  20. public Transform TargetTransform { get; set; }
  21. public Quaternion TargetRotation { get; set; }
  22. public Action MotionFinished;
  23. public override void Run()
  24. {
  25. _isLerping = true;
  26. _timeStartedLerping = Time.time;
  27. _transform = SelfTransform != null ? SelfTransform : transform;
  28. base.Run();
  29. }
  30. private void FixedUpdate()
  31. {
  32. if (!IsRunning || !_isLerping)
  33. return;
  34. var timeSinceStarted = Time.time - _timeStartedLerping;
  35. var percentageComplete = timeSinceStarted / Speed;
  36. var nextStep = Vector3.Lerp(LaunchPosition, TargetPosition, percentageComplete);
  37. _transform.position = !IsArcMotionEnabled ? nextStep : GetArcMotionPos(LaunchPosition, nextStep, TargetPosition, ArcMotionHeight);
  38. if (ChangeRotation)
  39. {
  40. Quaternion targetRotation;
  41. if (LookAtTarget)
  42. {
  43. var direction = TargetTransform.position - _transform.position;
  44. targetRotation = Quaternion.LookRotation(direction);
  45. }
  46. else
  47. {
  48. targetRotation = TargetRotation;
  49. }
  50. _transform.rotation = Quaternion.RotateTowards(_transform.rotation, targetRotation, Turn);
  51. }
  52. if (percentageComplete > 1.0f)
  53. {
  54. _isLerping = false;
  55. if (MotionFinished != null)
  56. MotionFinished.Invoke();
  57. }
  58. }
  59. private static Vector3 GetArcMotionPos(Vector3 startPosition, Vector3 nextPos, Vector3 targetPosition, float arcHeight)
  60. {
  61. var x0 = startPosition.x;
  62. var x1 = targetPosition.x;
  63. var dist = x1 - x0;
  64. var nextX = nextPos.x;
  65. var nextZ = nextPos.z;
  66. var baseY = Mathf.Lerp(startPosition.y, targetPosition.y, (nextX - x0) / dist);
  67. var arc = arcHeight * (nextX - x0) * (nextX - x1) / (-0.25f * dist * dist);
  68. return new Vector3(nextX, baseY + arc, nextZ);
  69. }
  70. }
  71. }