diff --git a/Player.cs b/Player.cs deleted file mode 100644 index a2ce0dd..0000000 --- a/Player.cs +++ /dev/null @@ -1,158 +0,0 @@ -using Godot; -using System; - -public partial class Player : CharacterBody3D -{ - public float MouseSensitivity { get; set; } = 0.2F; - - /// Time after pressing the jump button a jump may occur late. - public TimeSpan JumpEarlyTime { get; set; } = TimeSpan.FromSeconds(0.2); - - /// Time after leaving a jumpable surface when a jump may still occur. - public TimeSpan JumpCoyoteTime { get; set; } = TimeSpan.FromSeconds(0.2); - - public Vector3 Gravity { get; set; } = new(0, -12.0F, 0); - public float JumpVelocity { get; set; } = 5.0F; - public float MoveAccel { get; set; } = 6.0F; - public float MaxMoveSpeed { get; set; } = 4.0F; - public float FrictionFloor { get; set; } = 12.0F; - public float FrictionAir { get; set; } = 2.0F; - - public enum MovementMode { Default, Flying, NoClip } - public MovementMode Movement { get; set; } = MovementMode.Default; - - - private Node3D _neckBone = null!; - private Node3D _headBone = null!; - private Camera3D _camera = null!; - - private DateTime? _jumpPressed = null; - private DateTime? _lastOnFloor = null; - - public bool IsSprinting { get; private set; } - - - public override void _Ready() - { - _neckBone = GetNode("Neck"); - _headBone = GetNode("Neck/Head"); - _camera = GetNode("Neck/Head/Camera"); - } - - public override void _Input(InputEvent ev) - { - // Inputs that are valid when the game is focused. - // =============================================== - - if (ev.IsAction("move_sprint")) - { - IsSprinting = ev.IsPressed(); - GetViewport().SetInputAsHandled(); - } - - if (ev.IsActionPressed("move_jump")) - { - _jumpPressed = DateTime.Now; - GetViewport().SetInputAsHandled(); - } - - // Cycle movement mode between default, flying and flying+noclip. - if (ev.IsActionPressed("cycle_movement_mode")) - { - if (++Movement > MovementMode.NoClip) - Movement = MovementMode.Default; - GetViewport().SetInputAsHandled(); - } - - // Inputs that are valid only when the mouse is captured. - // ====================================================== - if (Input.MouseMode == Input.MouseModeEnum.Captured) { - } - } - - public override void _UnhandledInput(InputEvent ev) - { - var isMouseCaptured = Input.MouseMode == Input.MouseModeEnum.Captured; - // When pressing escape and mouse is currently captured, release it. - if (ev.IsActionPressed("ui_cancel") && isMouseCaptured) - Input.MouseMode = Input.MouseModeEnum.Visible; - - // Grab the mouse when pressing the primary mouse button. - // TODO: Make "primary mouse button" configurable. - if (ev is InputEventMouseButton button && button.ButtonIndex == MouseButton.Left) - Input.MouseMode = Input.MouseModeEnum.Captured; - - if (ev is InputEventMouseMotion motion && isMouseCaptured) - { - _neckBone.RotateX(Mathf.DegToRad(motion.Relative.Y * -MouseSensitivity)); - _headBone.RotateY(Mathf.DegToRad(motion.Relative.X * -MouseSensitivity)); - - var rotation = _neckBone.RotationDegrees; - rotation.X = Mathf.Clamp(rotation.X, -80, 80); - _neckBone.RotationDegrees = rotation; - } - } - - public override void _PhysicsProcess(double delta) - { - var movementVector = new Vector3( - Input.GetActionStrength("move_strafe_right") - Input.GetActionStrength("move_strafe_left"), - Input.GetActionStrength("move_upward") - Input.GetActionStrength("move_downward"), - Input.GetActionStrength("move_backward") - Input.GetActionStrength("move_forward")); - - if (Movement == MovementMode.Default) - { - Velocity += Gravity * (float)delta; - - var dir = Vector3.Zero; - var camTransform = _camera.GlobalTransform; - dir += camTransform.Basis.Z.Normalized() * movementVector.Z; - dir += camTransform.Basis.X.Normalized() * movementVector.X; - dir.Y = 0; - dir = dir.Normalized() * movementVector.Length(); - - var hvel = Velocity; - hvel.Y = 0; - - var target = dir * MaxMoveSpeed; - var friction = IsOnFloor() ? FrictionFloor : FrictionAir; - var accel = (dir.Dot(hvel) > 0) ? MoveAccel : friction; - - if (IsSprinting) { target *= 5; accel *= 5; } - hvel = hvel.Lerp(target, accel * (float)delta); - - Velocity = new(hvel.X, Velocity.Y, hvel.Z); - - // Sometimes, when pushing into a wall, jumping wasn't working. - // Possibly due to `IsOnFloor` returning `false` for some reason. - // The `JumpEarlyTime` feature seems to avoid this issue, thankfully. - - if (IsOnFloor()) _lastOnFloor = DateTime.Now; - - if (((DateTime.Now - _jumpPressed) <= JumpEarlyTime) - && ((DateTime.Now - _lastOnFloor) <= JumpCoyoteTime)) - { - Velocity = new(Velocity.X, JumpVelocity, Velocity.Z); - _jumpPressed = null; - _lastOnFloor = null; - } - } - else - { - Velocity *= 1 - FrictionAir * (float)delta; - - var cameraRot = _headBone.GlobalTransform.Basis.GetRotationQuaternion(); - var dir = cameraRot * movementVector; - var target = dir * MaxMoveSpeed; - var accel = (dir.Dot(Velocity) > 0) ? MoveAccel : FrictionAir; - target *= 4; accel *= 4; - - if (IsSprinting) { target *= 5; accel *= 5; } - Velocity = Velocity.Lerp(target, accel * (float)delta); - } - - if (Movement == MovementMode.NoClip) - Translate(Velocity * (float)delta); - else MoveAndSlide(); - } -}