174 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C#
		
	
	
	
| using System.Collections;
 | |
| using System.Collections.Generic;
 | |
| using System.Text.RegularExpressions;
 | |
| using System.Text;
 | |
| using Godot;
 | |
| 
 | |
| namespace Rokojori
 | |
| {  
 | |
|   [Tool]
 | |
|   [GlobalClass]
 | |
|   public partial class Shake:SequenceAction, Animator
 | |
|   { 
 | |
|     [Export]
 | |
|     public ShakeEffect shakeEffect;
 | |
| 
 | |
|     [Export]
 | |
|     public Node3D[] targets;
 | |
| 
 | |
|     List<TransformData> _targetValues;
 | |
| 
 | |
|     int _actionID = -1;
 | |
|     int _currentSpanAnimationID = -1;
 | |
| 
 | |
|     public void OnAnimatorStart(){}
 | |
|     public void OnAnimatorEnd(){}
 | |
|     public void OnAnimatorCancel(){}
 | |
| 
 | |
|     protected override void _OnTrigger()
 | |
|     {
 | |
|       if ( _actionID != -1 )
 | |
|       {
 | |
|         CancelAction( _actionID );
 | |
|       }
 | |
| 
 | |
|       _actionID = DispatchStart(); 
 | |
| 
 | |
|       var random = LCG.Randomized();
 | |
| 
 | |
|       var networkSeed = random.GetSeed();
 | |
| 
 | |
|       var randomization  = shakeEffect.shakeAmountCurve.Randomize( random );
 | |
|       var timeline = shakeEffect.timeline;
 | |
| 
 | |
|       var duration = shakeEffect.shakeAmountCurve.GetRandomizedEndTime( randomization );
 | |
|       var curve = shakeEffect;
 | |
| 
 | |
|       var start = TimeLineManager.GetPosition( shakeEffect.timeline );
 | |
| 
 | |
|       var keyFrames = new List<KeyFrame<TransformData>>();
 | |
|       var elapsed = 0f;
 | |
| 
 | |
|       while ( elapsed < duration )
 | |
|       {
 | |
|         var key = new KeyFrame<TransformData>();
 | |
|         key.data = shakeEffect.GetShakeData( elapsed, randomization, random );        
 | |
|         key.time = elapsed;
 | |
|         keyFrames.Add( key );
 | |
| 
 | |
|         elapsed += 1f / shakeEffect.GetShakeChangeFPSRandomized( elapsed, random );
 | |
|       }
 | |
|       
 | |
|       var kfAnimation = new KeyFrameAnimation<TransformData>();
 | |
|       kfAnimation.keyFrames = keyFrames;
 | |
|       kfAnimation.FlagSorted();
 | |
| 
 | |
|       KeyFrame<TransformData> lastKeyFrame = null;
 | |
| 
 | |
|       AnimationManager.StartAnimation( this, targets, AnimationMember.Transform );
 | |
| 
 | |
|       if ( _targetValues == null || _targetValues.Count == 0 )
 | |
|       {
 | |
|         _targetValues = Lists.Map( targets, t => TransformData.From( t, shakeEffect.globalPosition, shakeEffect.globalRotation ) );
 | |
|       }
 | |
|       
 | |
| 
 | |
| 
 | |
|       _currentSpanAnimationID = TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration, 
 | |
|         ( int spanAnimationID, TimeLineSpanUpdateType type )=>
 | |
|         {     
 | |
|           if ( spanAnimationID != _currentSpanAnimationID )
 | |
|           {
 | |
|             return;
 | |
|           }
 | |
|           
 | |
|           if ( ! AnimationManager.IsAnimating( this, targets, AnimationMember.Transform ) )
 | |
|           {
 | |
|             return;
 | |
|           }
 | |
| 
 | |
| 
 | |
|           if ( TimeLineSpanUpdateType.End == type )
 | |
|           {
 | |
|             AnimationManager.EndAnimation( this, targets, AnimationMember.Transform );
 | |
| 
 | |
|             for ( int i = 0; i < targets.Length; i++ )
 | |
|             {            
 | |
|               var o = _targetValues[ i ];
 | |
| 
 | |
|               o.Set( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation );
 | |
|             }
 | |
| 
 | |
|             _targetValues.Clear();
 | |
|             _actionID = -1;
 | |
|             _currentSpanAnimationID = -1;
 | |
| 
 | |
|             return;
 | |
|           }
 | |
| 
 | |
|          
 | |
|           var offset = TimeLineManager.GetPosition( shakeEffect.timeline ) - start;
 | |
|           var keyFrame = kfAnimation.GetKeyFrameAt( offset );
 | |
| 
 | |
|           if ( keyFrame == lastKeyFrame && ! shakeEffect.smooth )
 | |
|           {
 | |
|             return;
 | |
|           }
 | |
| 
 | |
|           var offsetData = keyFrame.data;
 | |
|           var delta = shakeEffect.timeline.delta;
 | |
| 
 | |
|           for ( int i = 0; i < targets.Length; i++ )
 | |
|           {
 | |
|             var combined = offsetData.Clone();
 | |
|             
 | |
|             var o = _targetValues[ i ];
 | |
|             
 | |
|             if ( shakeEffect.scaleShakeIsRelative )
 | |
|             {
 | |
|               combined.scale *= _targetValues[ i ].scale;
 | |
|             }
 | |
| 
 | |
|             combined.rotation *= MathX.DegreesToRadians;
 | |
| 
 | |
|             var beforeAdd = combined.Clone();
 | |
|             
 | |
|             combined.Add( o );
 | |
|             
 | |
|             // this.LogInfo( "Applying:", beforeAdd, " + ", o, "=", combined );
 | |
| 
 | |
| 
 | |
|             if ( shakeEffect.smooth )
 | |
|             {
 | |
|               var rawSmooth = Mathf.Clamp( shakeEffect.smoothingStrength, 0, 1 );
 | |
|               rawSmooth = Mathf.Pow( 1f - rawSmooth, 3 );
 | |
|               var smoothStrength = rawSmooth * 250f;
 | |
| 
 | |
|               var current = TransformData.From( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation );
 | |
|               combined.position = Smoother.SmoothTimeInvariant( current.position, combined.position, delta, smoothStrength );
 | |
|               combined.rotation = Smoother.SmoothTimeInvariant( current.rotation, combined.rotation, delta, smoothStrength );
 | |
|               combined.scale = Smoother.SmoothTimeInvariant( current.scale, combined.scale, delta, smoothStrength );
 | |
|             }
 | |
| 
 | |
|             combined.Set( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation );
 | |
|           }
 | |
| 
 | |
|           lastKeyFrame = keyFrame;
 | |
|         }
 | |
|       );
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public override void CancelAction( int actionID )
 | |
|     {
 | |
|       if ( actionID != _actionID )
 | |
|       {
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       AnimationManager.EndAnimation( this, targets, AnimationMember.Transform );  
 | |
|       _actionID = -1;
 | |
|       _currentSpanAnimationID = -1;
 | |
|     }
 | |
|   }
 | |
| } |