using DG.Tweening;
using System;
using UnityEngine;
using XGame.Framework.FGUI;
using XGame.Framework.Interfaces;
using XGame.Framework.Time;
namespace FL.FGUI.Actions
{
///
/// MoveLineAction的参数
///
public struct UIMoveActionArgs
{
public Vector3 from;
public Vector3 to;
///
/// 单位:毫秒
///
public int duration;
///
/// 延迟,单位: 毫秒
///
public int delay;
public float offset;
public Ease ease;
public Action onUpdate;
public Action onComplete;
}
public class UIMoveBezierAction : IAction, IPauseable, ITimeScalable
{
public UIMoveActionArgs 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()
{
_tween?.Kill();
_tween = null;
args = default;
_paused = false;
}
public void Start(FguiViewModel viewModel)
{
// 贝塞尔曲线运动
viewModel.Pos = args.from;
var timeScale = UnityEngine.Random.Range(0.2f, 0.8f);
var linePoint = Vector3.Lerp(args.from, args.to, timeScale);
var dir = Vector3.Cross(args.to - args.from, Vector3.forward).normalized; //运动方向的法线
var offset = args.offset > 0 ? args.offset : 300;
var disOffset = UnityEngine.Random.Range(-offset, offset);
var center = linePoint + dir * disOffset;
var totalTime = args.duration * 0.001f;
var timeTween = DOTween.To(() => 0, (t) =>
{
var tNormal = t / totalTime;
var pos = args.from.BezierPoint(center, args.to, tNormal);
viewModel.Pos = pos;
args.onUpdate.SafeInvoke(pos);
}, totalTime, totalTime);
if (args.delay > 0)
timeTween.SetDelay(args.delay * 0.001f);
timeTween.SetEase(args.ease == Ease.Unset ? Ease.OutQuad : args.ease);
_tween = timeTween;
timeTween.onComplete = () =>
{
var callback = args.onComplete;
_tween = null;
args = default;
callback?.Invoke();
};
}
void IAction.Start(FguiViewModel viewModel)
{
Start(viewModel);
}
void IPauseable.Pause()
{
if (_tween == null || _paused)
{
return;
}
_paused = true;
_tween.Pause();
}
void IPauseable.Resume()
{
if (_paused)
{
_paused = false;
_tween?.Play();
}
}
}
}