parent
							
								
									3ac59f082e
								
							
						
					
					
						commit
						f4708975d7
					
				
				 1 changed files with 0 additions and 158 deletions
			
			
		@ -1,158 +0,0 @@ | 
				
			||||
using Godot; | 
				
			||||
using System; | 
				
			||||
 | 
				
			||||
public partial class Player : CharacterBody3D | 
				
			||||
{ | 
				
			||||
	public float MouseSensitivity { get; set; } = 0.2F; | 
				
			||||
 | 
				
			||||
	/// <summary> Time after pressing the jump button a jump may occur late. </summary> | 
				
			||||
	public TimeSpan JumpEarlyTime { get; set; } = TimeSpan.FromSeconds(0.2); | 
				
			||||
 | 
				
			||||
	/// <summary> Time after leaving a jumpable surface when a jump may still occur. </summary> | 
				
			||||
	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<Node3D>("Neck"); | 
				
			||||
		_headBone = GetNode<Node3D>("Neck/Head"); | 
				
			||||
		_camera = GetNode<Camera3D>("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(); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue