using DG.Tweening; using System; using UnityEngine; using XGame.Framework.Interfaces; using XGame.Framework.Time; namespace FL.Battle.Actions { /// /// 曲线移动 /// internal class MoveCurveAction : IAction, IPauseable, ITimeScalable { public MoveActionArgs args; public AnimationCurve curve; public Vector3 curveOffset; 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; curve = null; curveOffset = Vector3.zero; _tween?.Kill(); _tween = null; _paused = false; } public void Start(Transform transform) { transform.position = args.from; var totalTime = args.duration * 0.001f; _tween = DOTween.To(() => 0, (t) => { var tNormal = t / totalTime; var pos = Vector3.Lerp(args.from, args.to, tNormal) + curve.Evaluate(tNormal) * curveOffset; 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.Linear : args.ease); _tween.onComplete += () => { var callback = args.onComplete; _tween = null; args = default; curve = null; curveOffset = Vector3.zero; callback.SafeInvoke(); }; } void IPauseable.Pause() { if (_tween == null || _paused) { return; } _paused = true; _tween.Pause(); } void IPauseable.Resume() { if (_paused) { _paused = false; _tween?.Play(); } } } }