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

231 lines
5.8 KiB
C#

using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass ]
public partial class TweenMaterial : SequenceAction, Animator
{
public void OnAnimatorStart(){}
public void OnAnimatorEnd(){}
public void OnAnimatorCancel(){}
// [Export]
// public Material fromMaterial;
[Export]
public Material toMaterial;
[Export]
public TweenType tweenType = new TweenTimeCurve();
[Export]
public TimeLine timeLine;
ColorProperty[] colors = [];
FloatProperty[] floats = [];
public enum MaterialAssignmentMode
{
No_Assignment,
Assignment_Once,
Unique_Once,
Temporary_Duplicate_For_Each_Tween
}
// [Export]
// public
MaterialAssignmentMode assignmentMode = MaterialAssignmentMode.Temporary_Duplicate_For_Each_Tween;
[ExportGroup( "Target")]
[Export]
public Node3D target;
[Export]
public MaterialSlot slot = MaterialSlot.None;
[Export]
public int index = 0;
// [ExportToolButton( "Assign From-Material")]
// public Callable AssignFromMaterialButton => Callable.From(
// () =>
// {
// MaterialSurfaceContainer.SetMaterialInSlot( target, index, slot, fromMaterial );
// }
// );
[ExportToolButton( "Assign To-Material")]
public Callable AssignToMaterialButton => Callable.From(
() =>
{
MaterialSurfaceContainer.SetMaterialInSlot( target, index, slot, toMaterial );
}
);
[ExportToolButton( "Get Material Delta")]
public Callable GetMaterialDeltaButton => Callable.From(
() =>
{
var from = MaterialSurfaceContainer.GetMaterialInSlot<Material>( target, index, slot );
this.LogInfo( "Delta", MaterialDelta.Create( from, toMaterial ) );
}
);
Material _assignedMaterial = null;
protected override void _OnTrigger()
{
if ( toMaterial == null && this._assignedMaterial == null )
{
return;
}
var fromMaterial = MaterialSurfaceContainer.From( target, this.index ).GetMaterialInSlot<Material>( slot );
SetAssignedMaterial( fromMaterial );
var tl = TimeLineManager.Ensure( timeLine );
var start = tl.position;
var delta = MaterialDelta.Create( fromMaterial, toMaterial );
this.LogInfo( "Delta:", delta );
colors = delta.colorProperties.ToArray();
floats = delta.floatProperties.ToArray();
var startColors = new Color[ colors.Length ];
var startFloats = new float[ floats.Length ];
var elementIndex = 0;
foreach ( var c in colors )
{
AnimationManager.StartAnimation( this, _assignedMaterial, c.propertyName );
startColors[ elementIndex ] = c.propertyName.Get( fromMaterial );
elementIndex ++;
}
elementIndex = 0;
foreach ( var f in floats )
{
AnimationManager.StartAnimation( this, _assignedMaterial, f.propertyName );
startFloats[ elementIndex ] = f.propertyName.Get( fromMaterial );
elementIndex ++;
}
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 elementIndex = 0;
var state = tweenType.GetTweenPhaseForPhase( span.phase );
foreach ( var c in colors )
{
if ( AnimationManager.IsAnimating( this, _assignedMaterial, c.propertyName ) )
{
c.ApplyLerped( _assignedMaterial, startColors[ elementIndex ], state );
}
elementIndex ++;
}
elementIndex = 0;
foreach ( var f in floats )
{
if ( AnimationManager.IsAnimating( this, _assignedMaterial, f.propertyName ) )
{
f.ApplyLerped( _assignedMaterial, startFloats[ elementIndex ], state );
}
elementIndex ++;
}
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 );
}
if ( MaterialAssignmentMode.Temporary_Duplicate_For_Each_Tween == assignmentMode )
{
_assignedMaterial = null;
var msc = MaterialSurfaceContainer.From( target, index );
msc.SetMaterialInSlot( slot, toMaterial );
}
DispatchEnd( sequenceID );
}
}
);
}
void SetAssignedMaterial( Material material )
{
if ( MaterialAssignmentMode.Temporary_Duplicate_For_Each_Tween == assignmentMode )
{
_assignedMaterial = (Material)material.Duplicate();
var tmsc = MaterialSurfaceContainer.From( target, index );
tmsc.SetMaterialInSlot( slot, _assignedMaterial );
return;
}
if ( _assignedMaterial != null )
{
return;
}
if ( MaterialAssignmentMode.No_Assignment == assignmentMode )
{
_assignedMaterial = toMaterial;
return;
}
_assignedMaterial = toMaterial;
if ( MaterialAssignmentMode.Unique_Once == assignmentMode )
{
_assignedMaterial = (Material)toMaterial.Duplicate();
}
var msc = MaterialSurfaceContainer.From( target, index );
msc.SetMaterialInSlot( slot, _assignedMaterial );
}
}
}