SmoothMove.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using System;
  2. using System.Collections;
  3. using UnityEngine;
  4. namespace ARLocation.Utils
  5. {
  6. public class SmoothMove : MonoBehaviour
  7. {
  8. public enum Mode
  9. {
  10. Horizontal,
  11. Full
  12. }
  13. [Tooltip("The smoothing factor."), Range(0, 1)]
  14. public float Epsilon = 0.5f;
  15. [Tooltip("The Precision."), Range(0, 0.1f)]
  16. public float Precision = 0.05f;
  17. public Vector3 Target
  18. {
  19. get { return target; }
  20. set
  21. {
  22. target = value;
  23. if (co != null)
  24. {
  25. StopCoroutine(co);
  26. }
  27. co = MoveTo(target);
  28. StartCoroutine(MoveTo(target));
  29. }
  30. }
  31. [Tooltip("The mode. If set to 'Horizontal', will leave the y component unchanged. Full means the object will move in all 3D coordinates.")]
  32. public Mode SmoothMoveMode = Mode.Full;
  33. private Vector3 target;
  34. private Action onTargetReached;
  35. private IEnumerator co;
  36. public void Move(Vector3 to, Action callback = null)
  37. {
  38. onTargetReached = callback;
  39. Target = to;
  40. }
  41. private IEnumerator MoveTo(Vector3 pTarget)
  42. {
  43. if (SmoothMoveMode == Mode.Horizontal)
  44. {
  45. Vector2 horizontalPosition = MathUtils.HorizontalVector(transform.position);
  46. Vector2 horizontalTarget = MathUtils.HorizontalVector(pTarget);
  47. while (Vector2.Distance(horizontalPosition, horizontalTarget) > Precision)
  48. {
  49. float t = 1.0f - Mathf.Pow(Epsilon, Time.deltaTime);
  50. horizontalPosition = Vector3.Lerp(horizontalPosition, horizontalTarget, t);
  51. transform.position = MathUtils.HorizontalVectorToVector3(horizontalPosition, transform.position.y);
  52. yield return null;
  53. }
  54. transform.position = MathUtils.HorizontalVectorToVector3(horizontalTarget, transform.position.y);
  55. onTargetReached?.Invoke();
  56. onTargetReached = null;
  57. }
  58. else
  59. {
  60. while (Vector3.Distance(transform.position, pTarget) > Precision)
  61. {
  62. float t = 1.0f - Mathf.Pow(Epsilon, Time.deltaTime);
  63. transform.position = Vector3.Lerp(transform.position, pTarget, t);
  64. yield return null;
  65. }
  66. transform.position = pTarget;
  67. onTargetReached?.Invoke();
  68. onTargetReached = null;
  69. }
  70. }
  71. public static SmoothMove AddSmoothMove(GameObject go, float epsilon)
  72. {
  73. var smoothMove = go.AddComponent<SmoothMove>();
  74. smoothMove.Epsilon = epsilon;
  75. return smoothMove;
  76. }
  77. }
  78. }