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

179 lines
3.8 KiB
C#
Raw Normal View History

2025-05-27 06:51:48 +00:00
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass ]
public partial class TweenMaterial : SequenceAction, Animator
{
public void OnAnimatorStart(){}
public void OnAnimatorEnd(){}
public void OnAnimatorCancel(){}
[Export]
public Material material;
[Export]
public float duration;
[Export]
public Curve tweenCurve = MathX.Curve( 0, 1 );
[Export]
public TimeLine timeLine;
[Export]
public ColorProperty[] colors = [];
[Export]
public FloatProperty[] floats = [];
public enum MaterialAssignmentMode
{
No_Assignment,
Assignment,
Unique_Assignment
}
[ExportGroup( "Target Assignment")]
[Export]
public MaterialAssignmentMode assignmentMode;
[Export]
public Node3D target;
[Export]
public MaterialSlot slot = MaterialSlot.None;
[Export]
public int index = 0;
Material _assignedMaterial = null;
protected override void _OnTrigger()
{
if ( material == null && _assignedMaterial == null )
{
return;
}
SetAssignedMaterial();
var tl = TimeLineManager.Ensure( timeLine );
var start = tl.position;
var startColors = new Color[ colors.Length ];
var startFloats = new float[ floats.Length ];
var index = 0;
var assignedMaterial = _assignedMaterial;
foreach ( var c in colors )
{
AnimationManager.StartAnimation( this, assignedMaterial, c.propertyName );
startColors[ index ] = c.propertyName.Get( assignedMaterial );
index ++;
}
index = 0;
foreach ( var f in floats )
{
AnimationManager.StartAnimation( this, assignedMaterial, f.propertyName );
startFloats[ index ] = f.propertyName.Get( assignedMaterial );
index ++;
}
var sequenceID = DispatchStart();
TimeLineManager.ScheduleSpanIn( tl, 0, duration,
( span, type )=>
{
var timeNow = tl.position;
var elapsed = timeNow - start;
var index = 0;
var state = span.phase;
if ( tweenCurve != null )
{
state = tweenCurve.Sample( state );
}
foreach ( var c in colors )
{
if ( AnimationManager.IsAnimating( this, assignedMaterial, c.propertyName ) )
{
c.ApplyLerped( assignedMaterial, startColors[ index ], state );
}
index ++;
}
index = 0;
foreach ( var f in floats )
{
if ( AnimationManager.IsAnimating( this, assignedMaterial, f.propertyName ) )
{
f.ApplyLerped( assignedMaterial, startFloats[ index ], state );
}
index ++;
}
if ( type == TimeLineSpanUpdateType.End )
{
foreach ( var c in colors )
{
AnimationManager.EndAnimation( this, assignedMaterial, c.propertyName );
}
foreach ( var f in floats )
{
AnimationManager.EndAnimation( this, assignedMaterial, f.propertyName );
}
DispatchEnd( sequenceID );
}
}
);
}
void SetAssignedMaterial()
{
if ( _assignedMaterial != null )
{
return;
}
if ( MaterialAssignmentMode.No_Assignment == assignmentMode )
{
_assignedMaterial = material;
return;
}
_assignedMaterial = material;
if ( MaterialAssignmentMode.Unique_Assignment == assignmentMode )
{
_assignedMaterial = (Material)material.Duplicate();
}
var msc = MaterialSurfaceContainer.From( target, index );
msc.SetMaterialInSlot( slot, _assignedMaterial );
}
}
}