243 lines
5.4 KiB
C#
243 lines
5.4 KiB
C#
|
|
using System.Diagnostics;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using Godot;
|
|
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass]
|
|
public partial class ThirdPersonCamera:VirtualCamera3D
|
|
{
|
|
[Export]
|
|
public Node3D target;
|
|
|
|
[Export]
|
|
public Smoothing targetFollowSmoothing = new FrameSmoothing();
|
|
|
|
[ExportGroup("Yaw")]
|
|
|
|
[Export]
|
|
public float yawSpeed;
|
|
|
|
[Export]
|
|
public Sensor yawPositiveAxis;
|
|
|
|
[Export]
|
|
public Sensor yawNegativeAxis;
|
|
|
|
[Export]
|
|
public bool roundYaw = false;
|
|
|
|
[Export]
|
|
public int roundedYawResolution = 64;
|
|
|
|
[Export]
|
|
public float yaw = 0;
|
|
|
|
[Export]
|
|
public Smoothing yawSmoothing = new FrameSmoothing();
|
|
|
|
[Export]
|
|
public bool yawGoesBehindPlayer = true;
|
|
|
|
[Export]
|
|
public Smoothing yawToBehingSmoothing = new FrameSmoothing();
|
|
|
|
[Export]
|
|
public float yawBehindDelayDuration = 5;
|
|
|
|
[Export]
|
|
public float yawGoesBehindActivation = 0.1f;
|
|
|
|
[Export]
|
|
public float behindYaw = 0;
|
|
|
|
[Export]
|
|
public float currentYaw = 0;
|
|
|
|
[Export]
|
|
public float bcDelta = 0;
|
|
|
|
|
|
[ExportGroup("Pitch")]
|
|
|
|
[Export]
|
|
public float pitchSpeed;
|
|
|
|
[Export]
|
|
public Sensor pitchPositiveAxis;
|
|
|
|
[Export]
|
|
public Sensor pitchNegativeAxis;
|
|
|
|
[Export]
|
|
public bool pitchIsRelative = false;
|
|
|
|
[Export]
|
|
public float pitch = 0;
|
|
|
|
[Export]
|
|
public float minPitch = -10;
|
|
|
|
[Export]
|
|
public float maxPitch = 80;
|
|
|
|
public float normalizedPitch => MathX.NormalizeClamped( pitch, minPitch, maxPitch );
|
|
|
|
[Export]
|
|
public Smoothing pitchSmoothing = new FrameSmoothing();
|
|
|
|
[Export]
|
|
public bool pitchGoesBackToCenter = true;
|
|
|
|
[Export]
|
|
public Smoothing toCenterPitchSmoothing = new FrameSmoothing();
|
|
|
|
[Export]
|
|
public float centerPitchDelayDuration = 5;
|
|
|
|
[Export]
|
|
public float centerPitch = 30;
|
|
|
|
[Export]
|
|
public float centerPitchActivation = 0.1f;
|
|
|
|
[ExportGroup("Distance")]
|
|
[Export]
|
|
public Curve distanceForPitch = MathX.Curve( 1, 1 );
|
|
|
|
[Export]
|
|
public float distanceScale = 1;
|
|
|
|
[ExportGroup("Camera Offset")]
|
|
[Export]
|
|
public Vector3 offset;
|
|
|
|
|
|
float smoothedYaw = 0;
|
|
float smoothedPitch = 0;
|
|
float smoothedDistance = 0;
|
|
|
|
float _centerPitchActivation = 0;
|
|
float _yawBehindActivation = 0;
|
|
|
|
public override void _Process( double delta )
|
|
{
|
|
if ( target == null )
|
|
{
|
|
return;
|
|
}
|
|
|
|
behindYaw = Math3D.GlobalYawDegrees( target.GlobalForward() * -1 );
|
|
behindYaw = MathX.NormalizeAngle( behindYaw );
|
|
|
|
currentYaw = MathX.NormalizeAngle( yaw );
|
|
|
|
bcDelta = MathX.NormalizeAngle( MathX.AngleDelta( behindYaw, currentYaw ) );
|
|
|
|
var targetPosition = Smoothing.Apply( targetFollowSmoothing, target.GlobalPosition, (float) delta );
|
|
|
|
|
|
var yawAxis = Sensors.PolarAxis( yawNegativeAxis, yawPositiveAxis );
|
|
var pitchAxis = Sensors.PolarAxis( pitchNegativeAxis, pitchPositiveAxis );
|
|
|
|
|
|
yaw += yawAxis * yawSpeed * (float)delta;
|
|
|
|
if ( yawGoesBehindPlayer )
|
|
{
|
|
if ( Mathf.Abs( yawAxis ) < yawGoesBehindActivation )
|
|
{
|
|
_yawBehindActivation += (float)delta;
|
|
|
|
if ( yawGoesBehindPlayer && _yawBehindActivation > yawBehindDelayDuration )
|
|
{
|
|
yaw = Smoothing.ApplyDegreesWith( yawToBehingSmoothing, yaw, behindYaw, (float) delta );
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
_yawBehindActivation = 0;
|
|
}
|
|
}
|
|
|
|
// yaw = MathX.Repeat( yaw, 360f );
|
|
|
|
if ( pitchIsRelative )
|
|
{
|
|
pitch += pitchAxis * pitchSpeed * (float)delta;
|
|
pitch = Mathf.Clamp( pitch, minPitch, maxPitch );
|
|
|
|
if ( Mathf.Abs( pitchAxis ) < centerPitchActivation )
|
|
{
|
|
_centerPitchActivation += (float)delta;
|
|
|
|
if ( _centerPitchActivation > centerPitchDelayDuration )
|
|
{
|
|
pitch = Smoothing.ApplyWith( toCenterPitchSmoothing, pitch, centerPitch, (float) delta );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_centerPitchActivation = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pitch = Mathf.Remap( pitchAxis, -1, 1, minPitch, maxPitch );
|
|
}
|
|
|
|
|
|
|
|
// if ( Mathf.Abs( yaw - smoothedYaw ) > 180 )
|
|
// {
|
|
// if ( yaw > smoothedYaw )
|
|
// {
|
|
// smoothedYaw += 360;
|
|
// }
|
|
// else if ( yaw < smoothedYaw )
|
|
// {
|
|
// smoothedYaw -= 360;
|
|
// }
|
|
// }
|
|
|
|
var appliedYaw = yaw;
|
|
|
|
// if ( roundYaw )
|
|
// {
|
|
// appliedYaw = MathX.SnapRounded( yaw, 360f/roundedYawResolution );
|
|
// }
|
|
|
|
smoothedYaw = Smoothing.ApplyDegrees( yawSmoothing, appliedYaw, (float) delta );
|
|
|
|
|
|
smoothedPitch = Smoothing.Apply( pitchSmoothing, pitch, (float) delta );
|
|
|
|
// if ( pitchGoesBackToCenter )
|
|
// {
|
|
// pitch = toCenterPitchSmoothing.Smooth( centerPitch, (float) delta );
|
|
// }
|
|
|
|
|
|
// RJLog.Log( "Pitch", smoothedPitch );
|
|
|
|
// smoothedYaw = yaw;
|
|
// smoothedPitch = pitch;
|
|
var distance = distanceForPitch.Sample( MathX.NormalizeClamped( pitch, minPitch, maxPitch ) ) * distanceScale;
|
|
|
|
GlobalPosition = targetPosition + Math3D.YawPitchRotation( smoothedYaw, smoothedPitch ) * Vector3.Forward * distance;
|
|
|
|
LookAt( targetPosition, Vector3.Up, true );
|
|
|
|
GlobalPosition += this.GetOrientationBasedGlobalOffset( offset );
|
|
|
|
}
|
|
|
|
|
|
}
|
|
} |