using System; using Godot; namespace Rokojori { [Tool] [GlobalClass ] public partial class TweenPosition:SequenceAction { [Export] public Node3D target; [Export] public Mode positionSpace = Mode.Global; [Export] public Node3D endPosition; public enum Mode { Global, Local } [Export] public Vector3 endOffset; [Export] public TweenType tweenType = new TweenTimeCurve(); [Export] public bool cacheEndPositionOnStart = true; [Export] public TimeLine timeLine; Vector3 GetToPosition() { var toPosition = endOffset; if ( Mode.Global == positionSpace ) { if ( endPosition != null ) { toPosition += endPosition.GlobalPosition; } } else { if ( endPosition != null ) { toPosition += endPosition.Position; } } return toPosition; } protected override void _OnTrigger() { if ( target == null ) { return; } var tl = TimeLineManager.Ensure( timeLine ); var start = tl.position; var fromPosition = target.GetPosition( Mode.Global == positionSpace ); var toPosition = GetToPosition(); var sequenceID = DispatchStart(); var tweenType = this.tweenType; if ( tweenType == null ) { tweenType = TweenTimeCurve.defaultCurve; } TimeLineManager.ScheduleSpanIn( tl, 0, tweenType.GetTweenDuration(), ( span, type )=> { var timeNow = tl.position; var elapsed = timeNow - start; var state = tweenType.GetTweenPhaseForPhase( span.phase ); if ( ! cacheEndPositionOnStart ) { toPosition = GetToPosition(); } var lerpedPosition = fromPosition.Lerp( toPosition, state ); if ( Mode.Global == positionSpace ) { target.GlobalPosition = lerpedPosition; } else if ( Mode.Local == positionSpace ) { target.Position = lerpedPosition; } if ( type == TimeLineSpanUpdateType.End ) { DispatchEnd( sequenceID ); } } ); } } }