Skip to content

Instantly share code, notes, and snippets.

@inc0der
Last active October 12, 2022 05:34
Show Gist options
  • Save inc0der/1087f246e8ed446e86eac2949db383ee to your computer and use it in GitHub Desktop.
Save inc0der/1087f246e8ed446e86eac2949db383ee to your computer and use it in GitHub Desktop.
Basic FPS Controller for Godot 4
# 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