using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System; using Godot; namespace Rokojori { [Tool] [GlobalClass] public partial class CameraEffect:Resource { [Export] public CameraEffectTargetAnimationCurve[] animations; [Export] public RJTimeLine timeline; public float maxDuration { get { var max = 0f; for ( int i = 0; i < animations.Length; i++ ) { max = Mathf.Max( animations[ i ].duration, max ); } return max; } } } public class CameraEffectRunner { public CameraEffect effect; public Vector3 position; public Quaternion rotation; public float fov; public float timePosition = 0; public bool isFinished => timePosition >= effect.maxDuration; public float timelineOffset = 0; List randomOffsets = new List(); public CameraEffectRunner( CameraEffect effect ) { this.effect = effect; Start(); } void Start() { timelineOffset = TimeLineManager.GetPosition( effect.timeline ); randomOffsets = new List(); Arrays.ForEach( effect.animations, ( a => randomOffsets.Add( a.Randomize() ) ) ) ; } public void Update() { float timeLinePosition = TimeLineManager.GetPosition( effect.timeline ); timePosition = timeLinePosition - timelineOffset; position = Vector3.Zero; rotation = Quaternion.Identity; fov = 0; for ( int i = 0; i < effect.animations.Length; i++) { Apply( effect.animations[ i ], i ); } } void Apply( CameraEffectTargetAnimationCurve curve, int index ) { var value = curve.Sample( timePosition, randomOffsets[ index ] ); if ( curve.flipScaleYRandomly && GodotRandom.Get().FlipCoin() ) { value = -value; } if ( CameraEffectTargetType.Position_X == curve.target ) { position.X += value; } else if ( CameraEffectTargetType.Position_Y == curve.target ) { position.Y += value; } else if ( CameraEffectTargetType.Position_Z == curve.target ) { position.Z += value; } else if ( CameraEffectTargetType.Rotation_X == curve.target ) { rotation *= Math3D.RotateXDegrees( value ); } else if ( CameraEffectTargetType.Rotation_Y == curve.target ) { rotation *= Math3D.RotateYDegrees( value ); } else if ( CameraEffectTargetType.Rotation_Z == curve.target ) { rotation *= Math3D.RotateZDegrees( value ); } else if ( CameraEffectTargetType.FOV == curve.target ) { fov += value; } } } }