rj-action-library/Runtime/Actions/Node3D/TweenAudio.cs

140 lines
3.0 KiB
C#
Raw Normal View History

2025-06-12 14:04:15 +00:00
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass ]
public partial class TweenAudio:SequenceAction, Animator
{
[Export]
public AudioStreamPlayer3D target;
[Export(PropertyHint.Range, "-80,80")]
public float endVolumeDB;
[Export]
public bool tweenInLinearAmplitude = true;
[Export]
public bool changePlayState = true;
[Export]
public float changingPlayStateTresholdDB = -40f;
[Export]
public TweenType tweenType = new TweenTimeCurve();
[Export]
public bool cacheEndVolumeOnStart = true;
[Export]
public TimeLine timeLine;
public void OnAnimatorStart(){}
public void OnAnimatorEnd(){}
public void OnAnimatorCancel(){}
public float GetVolume( float volume )
{
if ( tweenInLinearAmplitude )
{
return MathAudio.DecibelsToAmplitude( volume );
}
return volume;
}
public float SetVolume( float volume )
{
if ( tweenInLinearAmplitude )
{
return MathAudio.AmplitudeToDecibels( volume );
}
return volume;
}
protected override void _OnTrigger()
{
if ( target == null )
{
return;
}
var tl = TimeLineManager.Ensure( timeLine );
var start = tl.position;
var fromVolume = GetVolume( target.VolumeDb );
var toVolume = GetVolume( endVolumeDB );
var sequenceID = DispatchStart();
var tweenType = this.tweenType;
if ( tweenType == null )
{
tweenType = TweenTimeCurve.defaultCurve;
}
if ( changePlayState && toVolume > changingPlayStateTresholdDB )
{
// this.LogInfo( "Play" );
target.Playing = true;
target.Play( 0 );
}
AnimationManager.StartAnimation( this, target, AnimationMember.VolumeDB );
TimeLineManager.ScheduleSpanIn( tl, 0, tweenType.GetTweenDuration(),
( span, type )=>
{
if ( ! AnimationManager.IsAnimating( this, target, AnimationMember.VolumeDB ) )
{
return;
}
var timeNow = tl.position;
var elapsed = timeNow - start;
var state = tweenType.GetTweenPhaseForPhase( span.phase );
if ( ! cacheEndVolumeOnStart )
{
toVolume = GetVolume( endVolumeDB );
}
var lerpedVolume = Mathf.Lerp( fromVolume, toVolume, state );
target.VolumeDb = SetVolume( lerpedVolume );
// this.LogInfo( "Volume", lerpedVolume );
if ( type == TimeLineSpanUpdateType.End )
{
DispatchEnd( sequenceID );
AnimationManager.EndAnimation( this, target, AnimationMember.VolumeDB );
if ( changePlayState && SetVolume( toVolume ) < changingPlayStateTresholdDB )
{
// this.LogInfo( "Stop" );
target.Playing = false;
target.Stop();
}
}
}
);
}
}
}