Advanced character movement

PHOTO EMBED

Fri Feb 09 2024 22:36:16 GMT+0000 (Coordinated Universal Time)

Saved by @azariel

extends CharacterBody3D

@onready var nek = $nek
@onready var head = $nek/head
@onready var standing_collison_shape = $standing_collison_shape
@onready var crouching_collison_shape = $crouching_collison_shape
@onready var ray_cast_3d = $RayCast3D
@onready var camera_3d = $nek/head/Camera3D


var current_speed = 5.0

const walking_speed = 5.0
const sprinting_speed = 8.0
const crouching_speed = 3.0

const jump_velocity = 4.5

const mouse_sens = 0.089

var lerp_speed = 10.0

var free_look_tilt_amount = 8

var direction = Vector3.ZERO

var crouching_depth = -0.5

var walking = false
var sprinting = false
var crouching = false
var free_looking = false
var sliding = false

var slide_timer = 0.0
var slide_timer_max = 1.0

var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")

func _ready():
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event):
	if event is InputEventMouseMotion:
		if free_looking:
			nek.rotate_y(deg_to_rad(-event.relative.x * mouse_sens))
			nek.rotation.y = clamp(nek.rotation.y,deg_to_rad(-60),deg_to_rad(60))
		else:
			rotate_y(deg_to_rad(-event.relative.x * mouse_sens))
		head.rotate_x(deg_to_rad(-event.relative.y * mouse_sens))
		head.rotation.x = clamp(head.rotation.x,deg_to_rad(-89),deg_to_rad(89))
		


func _physics_process(delta):
	
	var input_dir = Input.get_vector("left", "right", "forward", "backward")
	
	if Input.is_action_pressed("crouch"):
		current_speed = crouching_speed
		head.position.y = lerp(head.position.y, crouching_depth,delta*lerp_speed)
		
		standing_collison_shape.disabled = true
		crouching_collison_shape.disabled = false
		
		if sprinting:
			sliding = true
			slide_timer = slide_timer_max
		
		walking = true
		sprinting = false
		crouching = false	
		

	elif !ray_cast_3d.is_colliding():
		
		
		standing_collison_shape.disabled = false
		crouching_collison_shape.disabled = true
		
		head.position.y = lerp(head.position.y,0.0,delta*lerp_speed)
		
		if Input.is_action_pressed("sprint"):
			
			current_speed = sprinting_speed
			
			walking = false
			sprinting = true
			crouching = false
			
		else:
			current_speed = walking_speed
			
			walking = true
			sprinting = false
			crouching = false
			
	#
	if Input.is_action_pressed("free_look"):
		free_looking = true
		camera_3d.rotation.z = -deg_to_rad(nek.rotation.y*free_look_tilt_amount)
	else:
		free_looking = false
		nek.rotation.y = lerp(nek.rotation.y,0.0,delta*lerp_speed)
		camera_3d.rotation.z = lerp(camera_3d.rotation.y,0.0,delta*lerp_speed)
		
	# Add the gravity.
	if not is_on_floor():
		velocity.y -= gravity * delta

	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = jump_velocity

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.

	direction = lerp(direction,(transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized(),delta*lerp_speed)
	if direction:
		velocity.x = direction.x * current_speed
		velocity.z = direction.z * current_speed
	else:
		velocity.x = move_toward(velocity.x, 0, current_speed)
		velocity.z = move_toward(velocity.z, 0, current_speed)

	move_and_slide()
content_copyCOPY