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

231 lines
5.8 KiB
C#
Raw Normal View History

2025-05-27 06:51:48 +00:00
2025-05-27 20:07:15 +00:00
using System;
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(){}
2025-05-27 20:07:15 +00:00
// [Export]
// public Material fromMaterial;
2025-05-27 06:51:48 +00:00
[Export]
2025-05-27 20:07:15 +00:00
public Material toMaterial;
2025-05-27 06:51:48 +00:00
[Export]
2025-05-27 20:07:15 +00:00
public TweenType tweenType = new TweenTimeCurve();
2025-05-27 06:51:48 +00:00
[Export]
public TimeLine timeLine;
2025-05-27 20:07:15 +00:00
ColorProperty[] colors = [];
2025-05-27 06:51:48 +00:00
2025-05-27 20:07:15 +00:00
FloatProperty[] floats = [];
2025-05-27 06:51:48 +00:00
public enum MaterialAssignmentMode
{
No_Assignment,
2025-05-27 20:07:15 +00:00
Assignment_Once,
Unique_Once,
Temporary_Duplicate_For_Each_Tween
2025-05-27 06:51:48 +00:00
}
2025-05-27 20:07:15 +00:00
// [Export]
// public
MaterialAssignmentMode assignmentMode = MaterialAssignmentMode.Temporary_Duplicate_For_Each_Tween;
2025-05-27 06:51:48 +00:00
2025-05-27 20:07:15 +00:00
[ExportGroup( "Target")]
2025-05-27 06:51:48 +00:00
[Export]
public Node3D target;
[Export]
public MaterialSlot slot = MaterialSlot.None;
[Export]
public int index = 0;
2025-05-27 20:07:15 +00:00
// [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 ) );
}
);
2025-05-27 06:51:48 +00:00
Material _assignedMaterial = null;
protected override void _OnTrigger()
{
2025-05-27 20:07:15 +00:00
if ( toMaterial == null && this._assignedMaterial == null )
2025-05-27 06:51:48 +00:00
{
return;
}
2025-05-27 20:07:15 +00:00
var fromMaterial = MaterialSurfaceContainer.From( target, this.index ).GetMaterialInSlot<Material>( slot );
SetAssignedMaterial( fromMaterial );
2025-05-27 06:51:48 +00:00
var tl = TimeLineManager.Ensure( timeLine );
var start = tl.position;
2025-05-27 20:07:15 +00:00
var delta = MaterialDelta.Create( fromMaterial, toMaterial );
this.LogInfo( "Delta:", delta );
colors = delta.colorProperties.ToArray();
floats = delta.floatProperties.ToArray();
2025-05-27 06:51:48 +00:00
var startColors = new Color[ colors.Length ];
var startFloats = new float[ floats.Length ];
2025-05-27 20:07:15 +00:00
var elementIndex = 0;
2025-05-27 06:51:48 +00:00
foreach ( var c in colors )
{
2025-05-27 20:07:15 +00:00
AnimationManager.StartAnimation( this, _assignedMaterial, c.propertyName );
startColors[ elementIndex ] = c.propertyName.Get( fromMaterial );
2025-05-27 06:51:48 +00:00
2025-05-27 20:07:15 +00:00
elementIndex ++;
2025-05-27 06:51:48 +00:00
}
2025-05-27 20:07:15 +00:00
elementIndex = 0;
2025-05-27 06:51:48 +00:00
foreach ( var f in floats )
{
2025-05-27 20:07:15 +00:00
AnimationManager.StartAnimation( this, _assignedMaterial, f.propertyName );
startFloats[ elementIndex ] = f.propertyName.Get( fromMaterial );
elementIndex ++;
2025-05-27 06:51:48 +00:00
}
var sequenceID = DispatchStart();
2025-05-27 20:07:15 +00:00
var tweenType = this.tweenType;
if ( tweenType == null )
{
tweenType = TweenTimeCurve.defaultCurve;
}
TimeLineManager.ScheduleSpanIn( tl, 0, tweenType.GetTweenDuration(),
2025-05-27 06:51:48 +00:00
( span, type )=>
{
var timeNow = tl.position;
var elapsed = timeNow - start;
2025-05-27 20:07:15 +00:00
var elementIndex = 0;
var state = tweenType.GetTweenPhaseForPhase( span.phase );
2025-05-27 06:51:48 +00:00
foreach ( var c in colors )
{
2025-05-27 20:07:15 +00:00
if ( AnimationManager.IsAnimating( this, _assignedMaterial, c.propertyName ) )
2025-05-27 06:51:48 +00:00
{
2025-05-27 20:07:15 +00:00
c.ApplyLerped( _assignedMaterial, startColors[ elementIndex ], state );
2025-05-27 06:51:48 +00:00
}
2025-05-27 20:07:15 +00:00
elementIndex ++;
2025-05-27 06:51:48 +00:00
}
2025-05-27 20:07:15 +00:00
elementIndex = 0;
2025-05-27 06:51:48 +00:00
foreach ( var f in floats )
{
2025-05-27 20:07:15 +00:00
if ( AnimationManager.IsAnimating( this, _assignedMaterial, f.propertyName ) )
2025-05-27 06:51:48 +00:00
{
2025-05-27 20:07:15 +00:00
f.ApplyLerped( _assignedMaterial, startFloats[ elementIndex ], state );
2025-05-27 06:51:48 +00:00
}
2025-05-27 20:07:15 +00:00
elementIndex ++;
2025-05-27 06:51:48 +00:00
}
if ( type == TimeLineSpanUpdateType.End )
{
foreach ( var c in colors )
{
2025-05-27 20:07:15 +00:00
AnimationManager.EndAnimation( this, _assignedMaterial, c.propertyName );
2025-05-27 06:51:48 +00:00
}
foreach ( var f in floats )
{
2025-05-27 20:07:15 +00:00
AnimationManager.EndAnimation( this, _assignedMaterial, f.propertyName );
2025-05-27 06:51:48 +00:00
}
2025-05-27 20:07:15 +00:00
if ( MaterialAssignmentMode.Temporary_Duplicate_For_Each_Tween == assignmentMode )
{
_assignedMaterial = null;
var msc = MaterialSurfaceContainer.From( target, index );
msc.SetMaterialInSlot( slot, toMaterial );
}
2025-05-27 06:51:48 +00:00
DispatchEnd( sequenceID );
}
}
);
}
2025-05-27 20:07:15 +00:00
void SetAssignedMaterial( Material material )
2025-05-27 06:51:48 +00:00
{
2025-05-27 20:07:15 +00:00
if ( MaterialAssignmentMode.Temporary_Duplicate_For_Each_Tween == assignmentMode )
{
_assignedMaterial = (Material)material.Duplicate();
var tmsc = MaterialSurfaceContainer.From( target, index );
tmsc.SetMaterialInSlot( slot, _assignedMaterial );
return;
}
2025-05-27 06:51:48 +00:00
if ( _assignedMaterial != null )
{
return;
}
if ( MaterialAssignmentMode.No_Assignment == assignmentMode )
{
2025-05-27 20:07:15 +00:00
_assignedMaterial = toMaterial;
2025-05-27 06:51:48 +00:00
return;
}
2025-05-27 20:07:15 +00:00
_assignedMaterial = toMaterial;
2025-05-27 06:51:48 +00:00
2025-05-27 20:07:15 +00:00
if ( MaterialAssignmentMode.Unique_Once == assignmentMode )
2025-05-27 06:51:48 +00:00
{
2025-05-27 20:07:15 +00:00
_assignedMaterial = (Material)toMaterial.Duplicate();
2025-05-27 06:51:48 +00:00
}
var msc = MaterialSurfaceContainer.From( target, index );
msc.SetMaterialInSlot( slot, _assignedMaterial );
}
}
}