111 lines
4.2 KiB
C#
111 lines
4.2 KiB
C#
using System;
|
|
using Godot;
|
|
using RustyOptions;
|
|
|
|
namespace Movementtests.systems;
|
|
|
|
public partial class HeadSystem : Node3D
|
|
{
|
|
private Camera3D _camera;
|
|
private Marker3D _cameraAnchor;
|
|
private AnimationPlayer _animationPlayer;
|
|
|
|
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
|
public float LookSensitivity { get; set; } = 1f;
|
|
|
|
[Export(PropertyHint.Range, "0.1,50,0.1,or_greater")]
|
|
public double CameraInclineAcceleration { get; set; } = 10f;
|
|
|
|
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
|
public float WallRunCameraIncline { get; set; } = 5f;
|
|
|
|
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
|
|
public float GroundedCameraIncline { get; set; } = 5f;
|
|
|
|
[Export(PropertyHint.Range, "0,2,0.1,or_greater")]
|
|
public float SlidingCameraHeightOffset { get; set; } = 1.0f;
|
|
|
|
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
|
public float SlidingJitterFrequency { get; set; } = 0.01f;
|
|
|
|
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
|
public float SlidingJitterAmplitude { get; set; } = 0.1f;
|
|
|
|
private FastNoiseLite _slidingNoise = new FastNoiseLite();
|
|
|
|
public void Init()
|
|
{
|
|
Input.SetMouseMode(Input.MouseModeEnum.Captured);
|
|
_camera = GetNode<Camera3D>("CameraSmooth/Camera3D");
|
|
_cameraAnchor = GetNode<Marker3D>("CameraAnchor");
|
|
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
|
|
|
|
_slidingNoise.NoiseType = FastNoiseLite.NoiseTypeEnum.Perlin;
|
|
_slidingNoise.SetFrequency(SlidingJitterFrequency);
|
|
}
|
|
|
|
public void OnMantle()
|
|
{
|
|
_animationPlayer.Play("mantle");
|
|
}
|
|
|
|
public void LookAround(double delta, Vector2 lookDir, Vector3 playerInput, Vector3 playerVelocity, Vector3? wallContactPoint = null, float sensitivitMultiplier = 1f, bool isSliding = false)
|
|
{
|
|
// Horizontal movement of head
|
|
float angleForHorizontalRotation = lookDir.X * LookSensitivity * sensitivitMultiplier;
|
|
RotateY(angleForHorizontalRotation);
|
|
|
|
// Vertical movement of head
|
|
Vector3 currentCameraRotation = _cameraAnchor.Rotation;
|
|
currentCameraRotation.X += Convert.ToSingle(lookDir.Y * LookSensitivity * sensitivitMultiplier);
|
|
currentCameraRotation.X = Mathf.Clamp(currentCameraRotation.X, Mathf.DegToRad(-90f), Mathf.DegToRad(90f));
|
|
|
|
// Camera incline on Wall and more
|
|
var isWallRunning = wallContactPoint.HasValue && wallContactPoint.Value.Length() > Mathf.Epsilon;
|
|
float cameraIncline;
|
|
if (isWallRunning)
|
|
{
|
|
var directionToWall = (wallContactPoint.Value - GlobalPosition).Normalized();
|
|
var cameraInclineFactor = ComputeCameraInclineFactor(directionToWall);
|
|
cameraIncline = Mathf.DegToRad(WallRunCameraIncline * cameraInclineFactor);
|
|
}
|
|
else
|
|
{
|
|
var cameraInclineFactor = ComputeCameraInclineFactor(playerInput);
|
|
cameraIncline = Mathf.DegToRad(GroundedCameraIncline * cameraInclineFactor * -1.0f);
|
|
}
|
|
currentCameraRotation.Z = (float) Mathf.Lerp(currentCameraRotation.Z, cameraIncline, delta * CameraInclineAcceleration);
|
|
_cameraAnchor.Rotation = currentCameraRotation;
|
|
|
|
if (isSliding)
|
|
{
|
|
_cameraAnchor.Position = Vector3.Down*SlidingCameraHeightOffset;
|
|
float noise1D = _slidingNoise.GetNoise1D(Time.GetTicksMsec());
|
|
float noiseAmplitude = SlidingJitterAmplitude*Mathf.Clamp(playerVelocity.Length(), 0f, 1f);
|
|
_cameraAnchor.Position += Vector3.Up*noise1D*noiseAmplitude;
|
|
}
|
|
else
|
|
{
|
|
_cameraAnchor.Position = Vector3.Zero;
|
|
}
|
|
|
|
_camera.GlobalTransform = _cameraAnchor.GetGlobalTransformInterpolated();
|
|
}
|
|
|
|
public float ComputeCameraInclineFactor(Vector3 direction)
|
|
{
|
|
var forward = GetForwardHorizontalVector().Normalized();
|
|
var crossProduct = forward.Cross(direction);
|
|
return crossProduct.Length()*Mathf.Sign(crossProduct.Y);
|
|
}
|
|
|
|
public Vector3 GetForwardHorizontalVector()
|
|
{
|
|
return GetGlobalTransform().Basis.Z;
|
|
}
|
|
|
|
public void SetHeight(float height)
|
|
{
|
|
Position = new Vector3(Position.X, height, Position.Z);
|
|
}
|
|
} |