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 = -80f; [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(); } } } ); } } }