using DG.Tweening; using FL.Battle.Actions; using System; using UnityEngine; using XGame.Framework; using XGame.Framework.Components; using XGame.Framework.Map; using XGame.Framework.Time; namespace FL.Battle.Components { public interface IMoveContext { /// /// 所有者的根节点 /// Transform OwnerTr { get; } } public enum EMoveType { /// /// 直线运动 /// DoTween.DOMove /// Line = 0, /// /// 贝塞尔曲线轨迹 /// Bezier, /// /// 抛物线 /// Parabola, /// /// AnimationCurve曲线 /// Curve, } /// /// 移动参数 /// public struct MoveArgs { public Vector3 target; public float speed; /// /// 时间缩放值,默认需要传1 /// public float timeScale; public EMoveType moveType; public Ease ease; /// /// 延迟,单位: 毫秒 /// public int delay; //public Action onUpdate; public Action onComplete; /// /// 曲线 /// EMoveType.Curve时有效 /// public AnimationCurve curve; /// /// 曲线的偏移量 /// EMoveType.Curve时有效 /// public Vector3 curveOffset; } /// /// DoTween.DOLocalMoveY /// public class MoveComponent : Component, IParallelTarget, IPauseable, ITimeScalable { private IAction _action; public Vector3 MoveDir { get; private set; } public bool IsMoving => _action != null; Vector3 IParallelTarget.Position => Context.OwnerTr.position; public float TimeScale { get { if (_action is ITimeScalable scalable) { return scalable.TimeScale; } return 1; } set { if (_action is ITimeScalable scalable) { scalable.TimeScale = value; } } } public void MoveTo(MoveArgs args) { var position = Context.OwnerTr.position; var duration = Mathf.RoundToInt(Vector3.Distance(args.target, position) * 1000 / args.speed); MoveDir = Vector3.Normalize(args.target - position); void OnCompleted() { ObjectPool.Recycle(_action); _action = null; MoveDir = Vector3.zero; args.onComplete.SafeInvoke(); } var actionArgs = new MoveActionArgs() { from = position, to = args.target, duration = duration, delay = args.delay, ease = args.ease, //onUpdate = args.onUpdate, onComplete = OnCompleted }; if (args.moveType is EMoveType.Line) { var move = ObjectPool.Acquire(); _action = move; move.args = actionArgs; move.Start(Context.OwnerTr); } else if (args.moveType is EMoveType.Bezier) { var move = ObjectPool.Acquire(); _action = move; move.args = actionArgs; move.Start(Context.OwnerTr, false); } else if (args.moveType is EMoveType.Curve) { var move = ObjectPool.Acquire(); _action = move; move.args = actionArgs; move.curve = args.curve; move.curveOffset = args.curveOffset; move.Start(Context.OwnerTr); } else { var move = ObjectPool.Acquire(); _action = move; move.args = actionArgs; move.Start(Context.OwnerTr); } if (args.timeScale != 1) { TimeScale = args.timeScale; } } public void Pause() { (_action as IPauseable)?.Pause(); } public void Resume() { (_action as IPauseable)?.Resume(); } public void StopMove() { if (_action != null) { ObjectPool.Recycle(_action); _action = null; MoveDir = Vector3.zero; } } protected override void OnDispose() { StopMove(); } } }