using Godot; public partial class Player : CharacterBody3D { [Signal] public delegate void OnHitEventHandler(); public const float _speed = 5.0f; public const float _jumpVelocity = 4.5f; [Export] private float _mouseSensitivity = 0.03f; [Export] private float _joystickDeadZone = 0.5f; [Export] private float _sensitivityHorizontal = 0.5f; [Export] private float _sensitivityVertical = 0.5f; [Export] private Node3D _pivot; private RayCast3D _aimCast; // Get the gravity from the project settings to be synced with RigidBody nodes. public static float gravity = ProjectSettings.GetSetting("physics/3d/default_gravity").AsSingle(); public override void _Ready() { Input.MouseMode = Input.MouseModeEnum.Captured; _aimCast = GetNode("Pivot/Camera3D/AimCast"); } public override void _PhysicsProcess(double delta) { var isOnFloor = IsOnFloor(); Velocity = MovePlayer(Velocity, Transform.Basis, (float)delta, isOnFloor); MoveAndSlide(); } public override void _Process(double delta) { var joyRightX = Input.GetJoyAxis(0, JoyAxis.RightX); var joyRightY = Input.GetJoyAxis(0, JoyAxis.RightY); if (Mathf.Abs(joyRightX) > _joystickDeadZone) RotateY(Mathf.DegToRad(-joyRightX * _sensitivityHorizontal)); if (Mathf.Abs(joyRightY) > _joystickDeadZone) { _pivot.RotateX(Mathf.DegToRad(-joyRightY * _sensitivityVertical)); _pivot.Rotation = new Vector3(Mathf.Clamp(_pivot.Rotation.X, Mathf.DegToRad(-80), Mathf.DegToRad(80)), _pivot.Rotation.Y, _pivot.Rotation.Z); } } public override void _Input(InputEvent @event) { if (Input.IsActionJustPressed("quit")) GetTree().Quit(); if (@event is InputEventMouseMotion inputMouseEvent) { RotateY(Mathf.DegToRad(-inputMouseEvent.Relative.X * _mouseSensitivity)); _pivot.RotateX(Mathf.DegToRad(-inputMouseEvent.Relative.Y * _mouseSensitivity)); _pivot.Rotation = new Vector3(Mathf.Clamp(_pivot.Rotation.X, Mathf.DegToRad(-80), Mathf.DegToRad(80)), _pivot.Rotation.Y, _pivot.Rotation.Z); } if (@event.IsActionPressed("fire") && _aimCast.IsColliding()) { EmitSignal(SignalName.OnHit); _aimCast.GetCollider().Call("OnHitEvent", 3); } } private static Vector3 MovePlayer(Vector3 velocity, Basis basis, float delta, bool isOnFloor) { var startingVelocity = velocity; // Add the gravity. if (!isOnFloor) velocity.Y -= gravity * delta; // Handle Jump. if (Input.IsActionJustPressed("jump") && isOnFloor) velocity.Y = _jumpVelocity; // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. Vector2 inputDir = Input.GetVector("left", "right", "up", "down"); Vector3 direction = (basis * new Vector3(inputDir.X, 0, inputDir.Y)).Normalized(); if (direction != Vector3.Zero) { velocity.X = direction.X * _speed; velocity.Z = direction.Z * _speed; } else { velocity.X = Mathf.MoveToward(startingVelocity.X, 0, _speed); velocity.Z = Mathf.MoveToward(startingVelocity.Z, 0, _speed); } return velocity; } }