rj-action-library/Runtime/Actions/Visual/TweenPosition.cs

127 lines
2.3 KiB
C#

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 );
}
}
);
}
}
}