extends CharacterBody3D
# The reason why we have this when defining a variable ":=" is due to godot being able...
# to infer types of variables, it's the same as static typing a variable such as 'var example: float = 2.0'
# Horizontal movement of the player
#Speed of the player, in m/s
@export var speed := 5.0
#Speed of the player, in m/s whilst sprinting
@export var sprint_speed := 8.0
#Take the springarm pos, so that our direction isn't based off the global axis, but rather the rotated camera
@onready var camera := $Node3D/CameraPivot
# Jump movement of the player
#How high the player jumps, keep in mind no longer negative due to cartisian plane no longer being inverted
@export var jump_velocity := 4.5
#Dashing of the player
#How far the player moves in metres when pressed
@export var dash_velocity := 50
# This is a flag check to see if the player has clicked dash, if so, halt movement such that only dash movement applies
var player_dashing := false
# To check if the player can dash, if this check does not exist, the player movement would purely be dashing
var can_dash := true
#Other variables needed
var levels: int
#Functions that the game calls/godot built in functions
func _physics_process(delta: float) -> void:
# In order to make code cleaner, code that needs to run every frame is first...
# defined and then called up in the process function
if player_dashing == false:
movement()
dash()
gravity(delta)
jump()
move_and_slide()
#Functions that have been made/non-godot specific functions
func movement() -> void:
# Get the input direction and handle the movement/deceleration.
var input_dir := Input.get_vector("left", "right", "forward", "backward")
var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
#Rotate the global axis by the camera rotaion so that the player moves with the camera
direction = direction.rotated(Vector3.UP, camera.global_rotation.y)
if direction: # When a key is pressed
# Note that it's the XZ plane, as the Y plane handles vertical movement
velocity.x = direction.x * speed # When x direction key pressed, move in x direction
velocity.z = direction.z * speed # Same here for z
else: # Friction
velocity.x = move_toward(velocity.x, 0, speed)
velocity.z = move_toward(velocity.z, 0, speed)
#Handles sprint, when shift pressed; run, else walk
if Input.is_action_pressed("sprint"):
velocity.x = direction.x * sprint_speed
velocity.z = direction.z * sprint_speed
func gravity(delta) -> void:
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
func jump() -> void:
# Handle jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
func dash():
if Input.is_action_just_released("dash") and can_dash == true:
#In order to dash, we need the forward vector, this var grabs it
var forward: Vector3 = -camera.transform.basis.z
#When the camera faces a certain direction, vector3 may not have the xyz plane be equal, leading to...
#inconsistant dashing, when normalized, the xyz plane where the player is facing is equal
forward = forward.normalized()
# Flag to say the player is dashing
player_dashing = true
# Flag to say the player can no longer dash
can_dash = false
# Player velocity is equal to the directon of the camera direction times by the dash vel.
velocity += forward * dash_velocity
#A dash timer, when ended, dashing ends
$DashTimer.start()
#Functions that are connected, such as signals
func _on_dash_timer_timeout() -> void:
#Play is no longer dashing
player_dashing = false
#Player can dash
can_dash = true
#When the dash ends, the xz plane stops due to the movement func, this ensures consistancy in the y plane
velocity.y = velocity.y / 4
For convenience sake, I’ve also commented the code if you want to understand it!
(Do keep in mind I’ve only been using the engine for 2 months, so some code may be wrong/could be optimised)
This is the structure of the player.
