using System; using Godot; namespace Rokojori { [Tool] [GlobalClass ] public partial class TweenFloatShaderProperty:SequenceAction, Animator { [Export] public Material material; [Export] public FloatPropertyName propertyName; [Export] public float endValue; [Export] public Duration duration; [Export] public Curve curve; public void OnAnimatorStart(){} public void OnAnimatorEnd(){} public void OnAnimatorCancel(){} int _actionID = -1; int _timeID = -1; [Export] public bool interruptCurrent = true; protected override void _OnTrigger() { if ( ! interruptCurrent && _actionID != -1 ) { // this.LogInfo( "Already running" ); return; } // this.LogInfo( "Started Float Tween" ); if ( Engine.IsEditorHint() ) { return; } if ( _actionID != -1 ) { CancelAction( _actionID ); } _actionID = DispatchStart(); var startValue = propertyName.Get( material ); AnimationManager.StartAnimation( this, material, propertyName ); // this.LogInfo( "Get Float Tween", startValue ); _timeID = TimeLineManager.ScheduleSpanWith( duration, ( span, type )=> { // this.LogInfo( "Update Float Tween", startValue ); if ( span.id != _timeID ) { return; } if ( ! AnimationManager.IsAnimating( this, material, propertyName ) ) { return; } var phase = span.phase; if ( curve != null ) { phase = curve.Sample( phase ); } var value = Mathf.Lerp( startValue, endValue, phase ); // this.LogInfo( "Updating Float Tween", "phase:", phase, "value:", value, target ); propertyName.Set( material, value ); // ReflectionHelper.SetValue( material, propertyName , value ); if ( type == TimeLineSpanUpdateType.End ) { // this.LogInfo( "End Float Tween", endValue ); // target._Set( targetMember, endValue ); propertyName.Set( material, endValue ); AnimationManager.EndAnimation( this, material, propertyName ); DispatchEnd( _actionID ); _actionID = -1; _timeID = -1; } } ).id; } } }