rj-action-library/Runtime/VirtualCameras/Effects/CameraEffect.cs

122 lines
2.7 KiB
C#

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<Vector3> randomOffsets = new List<Vector3>();
public CameraEffectRunner( CameraEffect effect )
{
this.effect = effect;
Start();
}
void Start()
{
timelineOffset = TimeLineManager.GetPosition( effect.timeline );
randomOffsets = new List<Vector3>();
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;
}
}
}
}