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; [Export] public bool pitchIsRelative = false; [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; [ExportGroup("Offset")] [Export] public Vector3 offset; Smoother distanceSmoother = new Smoother(); float smoothedYaw = 0; float smoothedPitch = 0; float smoothedDistance = 0; public override void _Process( double delta ) { if ( target == null ) { return; } var yawAxis = Sensors.PolarAxis( yawNegativeAxis, yawPositiveAxis ); var pitchAxis = Sensors.PolarAxis( pitchNegativeAxis, pitchPositiveAxis ); yaw += yawAxis * yawSpeed * (float)delta; // yaw = MathX.Repeat( yaw, 360f ); if ( pitchIsRelative ) { pitch += pitchAxis * pitchSpeed * (float)delta; pitch = Mathf.Clamp( pitch, minPitch, maxPitch ); } 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; } } smoothedYaw = yaw; smoothedPitch = pitchSmoother.SmoothForDuration( smoothedPitch, pitch, pitchSmoothingDuration, (float) delta ); // RJLog.Log( "Pitch", smoothedPitch ); // smoothedYaw = yaw; // smoothedPitch = pitch; var distance = distanceForPitch.Sample( MathX.NormalizeClamped( pitch, minPitch, maxPitch ) ) * distanceScale; GlobalPosition = target.GlobalPosition + Math3D.YawPitchRotation( smoothedYaw, smoothedPitch ) * Vector3.Forward * distance + offset; LookAt( target.GlobalPosition + offset, Vector3.Up, true ); } } }