using DG.Tweening; using System; using UnityEngine; using XGame.Framework.Interfaces; using XGame.Framework.Time; namespace FL.Battle.Actions { /// /// 抛物线移动 /// 中心点位置固定的贝塞尔曲线 /// internal class MoveParabolaAction : IAction, IPauseable, ITimeScalable { public MoveActionArgs args; private Tween _tween; private bool _paused; float ITimeScalable.TimeScale { get => _tween?.timeScale ?? 1; set { if (_tween == null) { return; } _tween.timeScale = value; } } void IReference.Clear() { args = default; _tween?.Kill(); _tween = null; _paused = false; } public void Start(Transform transform) { transform.position = args.from; var totalTime = args.duration * 0.001f; var center = Vector3.Lerp(args.from, args.to, 0.5f); // z轴向相机偏移 center.z -= 8; _tween = DOTween.To(() => 0, (t) => { var tNormal = t / totalTime; var pos = args.from.BezierPoint(center, args.to, tNormal); transform.position = pos; args.onUpdate.SafeInvoke(pos); }, totalTime, totalTime); if (args.delay > 0) { _tween.SetDelay(args.delay * 0.001f); } _tween.SetEase(args.ease == Ease.Unset ? Ease.OutQuad : args.ease); _tween.onComplete += () => { var callback = args.onComplete; _tween = null; args = default; callback.SafeInvoke(); }; } void IPauseable.Pause() { if (_tween == null || _paused) { return; } _paused = true; _tween.Pause(); } void IPauseable.Resume() { if (_paused) { _paused = false; _tween?.Play(); } } } }