MoveBezierAction.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using DG.Tweening;
  2. using System;
  3. using UnityEngine;
  4. using XGame.Framework.Interfaces;
  5. using XGame.Framework.Time;
  6. namespace FL.Battle.Actions
  7. {
  8. /// <summary>
  9. /// 贝塞尔移动
  10. /// 中心点位置随机
  11. /// </summary>
  12. internal class MoveBezierAction : IAction, IPauseable, ITimeScalable
  13. {
  14. public MoveActionArgs args;
  15. private Tween _tween;
  16. private bool _paused;
  17. float ITimeScalable.TimeScale
  18. {
  19. get => _tween?.timeScale ?? 1;
  20. set
  21. {
  22. if (_tween == null)
  23. {
  24. return;
  25. }
  26. _tween.timeScale = value;
  27. }
  28. }
  29. void IReference.Clear()
  30. {
  31. _tween?.Kill();
  32. _tween = null;
  33. args = default;
  34. _paused = false;
  35. }
  36. public void Start(Transform transform, bool isFoword)
  37. {
  38. //transform.DOPlayForward();
  39. // 贝塞尔曲线运动
  40. transform.position = args.from;
  41. var timeScale = UnityEngine.Random.Range(0.2f, 0.8f);
  42. var linePoint = Vector3.Lerp(args.from, args.to, timeScale);
  43. var dir = Vector3.Cross(args.to - args.from, Vector3.forward).normalized; //运动方向的法线
  44. // 沿Y轴上下运动时算出来z值为零,直接把x值赋值给z进行偏移
  45. if (dir.z == 0)
  46. dir.z = dir.x;
  47. var disOffset = UnityEngine.Random.Range(-3f, 3f);
  48. var center = linePoint + dir * disOffset;
  49. var totalTime = args.duration * 0.001f;
  50. var timeTween = DOTween.To(() => 0, (t) =>
  51. {
  52. var tNormal = t / totalTime;
  53. var pos = args.from.BezierPoint(center, args.to, tNormal);
  54. transform.position = pos;
  55. if (isFoword)
  56. {
  57. var tempDir = (args.to - pos).normalized;
  58. var rot = Vector3.zero;
  59. rot.z = Vector3.Angle(tempDir, Vector3.up);
  60. transform.localEulerAngles = rot;
  61. //if (tempDir != Vector3.zero)
  62. //{
  63. // transform.forward = tempDir;
  64. //}
  65. }
  66. args.onUpdate.SafeInvoke(pos);
  67. }, totalTime, totalTime);
  68. if (args.delay > 0)
  69. timeTween.SetDelay(args.delay * 0.001f);
  70. timeTween.SetEase(args.ease == Ease.Unset ? Ease.OutQuad : args.ease);
  71. _tween = timeTween;
  72. timeTween.onComplete = () =>
  73. {
  74. var callback = args.onComplete;
  75. _tween = null;
  76. args = default;
  77. callback?.Invoke();
  78. };
  79. }
  80. void IAction.Start(Transform transform)
  81. {
  82. Start(transform, true);
  83. }
  84. void IPauseable.Pause()
  85. {
  86. if (_tween == null || _paused)
  87. {
  88. return;
  89. }
  90. _paused = true;
  91. _tween.Pause();
  92. }
  93. void IPauseable.Resume()
  94. {
  95. if (_paused)
  96. {
  97. _paused = false;
  98. _tween?.Play();
  99. }
  100. }
  101. }
  102. }