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; public void Init() { Input.SetMouseMode(Input.MouseModeEnum.Captured); _camera = GetNode("CameraSmooth/Camera3D"); _cameraAnchor = GetNode("CameraAnchor"); _animationPlayer = GetNode("AnimationPlayer"); } public void OnMantle() { _animationPlayer.Play("mantle"); } public void LookAround(double delta, Vector2 lookDir, Vector3 playerVelocity, Vector3? wallContactPoint = null, float sensitivitMultiplier = 1f) { // 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)); var isWallRunning = wallContactPoint.HasValue && wallContactPoint.Value.Length() > Mathf.Epsilon; var cameraIncline = 0f; if (isWallRunning) { var directionToWall = (wallContactPoint.Value - GlobalPosition).Normalized(); var cameraInclineFactor = ComputeCameraInclineFactor(directionToWall); cameraIncline = Mathf.DegToRad(WallRunCameraIncline * cameraInclineFactor); } else { var cameraInclineFactor = ComputeCameraInclineFactor(playerVelocity); cameraIncline = Mathf.DegToRad(GroundedCameraIncline * cameraInclineFactor * -1.0f); } currentCameraRotation.Z = (float) Mathf.Lerp(currentCameraRotation.Z, cameraIncline, delta * CameraInclineAcceleration); _cameraAnchor.Rotation = currentCameraRotation; _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); } }