Last active
January 5, 2025 05:13
-
-
Save inc0der/1087f246e8ed446e86eac2949db383ee to your computer and use it in GitHub Desktop.
Basic FPS Controller for Godot 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# For Godot 4 Alpha 2 | |
# The head node should contain the camera, flashlight and other things that require a pivot/rotation | |
class_name BasicFpsController | |
extends CharacterBody3D | |
@export var MOVE_SPEED := 4.0 | |
@export var JUMP_FORCE := 4.5 | |
@export var SPRINT_SPEED := 6.0 | |
@export var GRAVITY := 9.8 | |
@export var ACCELERATION := 15.0 | |
@export var DEACCELERATION := 20.0 | |
@export var SPRINT_ACCEL := 7.0 | |
@export var MOUSE_SENSITIVITY := 0.10 | |
@export_node_path(Node3D) var head | |
@export var move_left_key := "left" | |
@export var move_right_key := "right" | |
@export var move_backward_key := "backward" | |
@export var move_forward_key := "forward" | |
@export var jump_key := "jump" | |
@export var sprint_key := "sprint" | |
var is_sprinting: bool = false | |
var is_jumping: bool = false | |
func _ready(): | |
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | |
head = get_node(head) | |
func _input(event): | |
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED: | |
rotate_y(deg2rad(event.relative.x * -1) * MOUSE_SENSITIVITY) | |
head.rotate_x(deg2rad(-event.relative.y * MOUSE_SENSITIVITY)) | |
head.rotation.x = clamp(head.rotation.x, deg2rad(-70), deg2rad(70)) | |
func movement_vector() -> Vector3: | |
var input_vector = Input.get_vector( | |
move_right_key, | |
move_left_key, | |
move_backward_key, | |
move_forward_key | |
) | |
return global_transform.basis * Vector3(input_vector.x, 0, input_vector.y) * -1 | |
func _physics_process(delta: float) -> void: | |
process_input(delta) | |
process_velocity(delta) | |
# warning-ignore:unused_argument | |
func process_input(delta) -> void: | |
is_jumping = Input.is_action_just_pressed(jump_key) | |
is_sprinting = Input.is_action_pressed(sprint_key) | |
# Capturing/Freeing the cursor | |
if Input.is_action_just_pressed("ui_cancel"): | |
if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE: | |
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | |
else: | |
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) | |
pass | |
func process_velocity(delta: float) -> void: | |
var speed = SPRINT_SPEED if is_sprinting else MOVE_SPEED | |
var target = movement_vector() * speed | |
var accel | |
if target.dot(motion_velocity) > 0.1: | |
accel = SPRINT_ACCEL if is_sprinting else ACCELERATION | |
else: | |
accel = DEACCELERATION | |
motion_velocity.y -= GRAVITY * delta | |
if is_jumping && is_on_floor(): | |
motion_velocity.y += JUMP_FORCE | |
motion_velocity.x = motion_velocity.move_toward(target, accel * delta).x | |
motion_velocity.z = motion_velocity.move_toward(target, accel * delta).z | |
move_and_slide() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment