rj-action-library/Runtime/VirtualCameras/ThirdPersonCamera.cs

139 lines
2.8 KiB
C#
Raw Normal View History

2024-12-01 17:07:41 +00:00
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;
[ExportGroup("Yaw")]
[Export]
public float yawSpeed;
[Export]
public RJSensor yawPositiveAxis;
[Export]
public RJSensor yawNegativeAxis;
[Export]
public float yaw = 0;
[Export]
public float yawSmoothingDuration = 0.1f;
Smoother yawSmoother = new Smoother();
[ExportGroup("Pitch")]
[Export]
public float pitchSpeed;
[Export]
public RJSensor pitchPositiveAxis;
[Export]
public RJSensor pitchNegativeAxis;
2025-01-03 12:09:23 +00:00
[Export]
public bool pitchIsRelative = false;
2024-12-01 17:07:41 +00:00
[Export]
public float pitch = 0;
[Export]
public float minPitch = -10;
[Export]
public float maxPitch = 80;
[Export]
public float pitchSmoothingDuration = 0.1f;
Smoother pitchSmoother = new Smoother();
[Export]
public Curve distanceForPitch = MathX.Curve( 1, 1 );
[Export]
public float distanceScale = 1;
2025-01-03 12:09:23 +00:00
[ExportGroup("Offset")]
[Export]
public Vector3 offset;
2024-12-01 17:07:41 +00:00
Smoother distanceSmoother = new Smoother();
float smoothedYaw = 0;
float smoothedPitch = 0;
float smoothedDistance = 0;
public override void _Process( double delta )
{
if ( target == null )
{
return;
}
2025-01-03 12:09:23 +00:00
var yawAxis = Sensors.PolarAxis( yawNegativeAxis, yawPositiveAxis );
2024-12-01 17:07:41 +00:00
var pitchAxis = Sensors.PolarAxis( pitchNegativeAxis, pitchPositiveAxis );
yaw += yawAxis * yawSpeed * (float)delta;
2025-01-03 12:09:23 +00:00
// yaw = MathX.Repeat( yaw, 360f );
2024-12-01 17:07:41 +00:00
2025-01-03 12:09:23 +00:00
if ( pitchIsRelative )
{
pitch += pitchAxis * pitchSpeed * (float)delta;
pitch = Mathf.Clamp( pitch, minPitch, maxPitch );
}
else
{
pitch = Mathf.Remap( pitchAxis, -1, 1, minPitch, maxPitch );
}
2024-12-01 17:07:41 +00:00
2025-01-03 12:09:23 +00:00
2024-12-01 17:07:41 +00:00
if ( Mathf.Abs( yaw - smoothedYaw ) > 180 )
{
if ( yaw > smoothedYaw )
{
smoothedYaw += 360;
}
else if ( yaw < smoothedYaw )
{
smoothedYaw -= 360;
}
}
smoothedYaw = yaw;
2025-01-03 12:09:23 +00:00
smoothedPitch = pitchSmoother.SmoothForDuration( smoothedPitch, pitch, pitchSmoothingDuration, (float) delta );
// RJLog.Log( "Pitch", smoothedPitch );
// smoothedYaw = yaw;
// smoothedPitch = pitch;
2024-12-01 17:07:41 +00:00
var distance = distanceForPitch.Sample( MathX.NormalizeClamped( pitch, minPitch, maxPitch ) ) * distanceScale;
2025-01-03 12:09:23 +00:00
GlobalPosition = target.GlobalPosition + Math3D.YawPitchRotation( smoothedYaw, smoothedPitch ) * Vector3.Forward * distance + offset;
2024-12-01 17:07:41 +00:00
2025-01-03 12:09:23 +00:00
LookAt( target.GlobalPosition + offset, Vector3.Up, true );
2024-12-01 17:07:41 +00:00
}
}
}