Godot Version
4.3
Question
I have been having trouble while creating a general character controller. As I tried to implement ground sliding, it didn’t work, and no matter what I tried, the crouch seemed to always be dominant, so I would really apreciate it if you would help me with this one.
here is the player code:
extends CharacterBody3D
#Export Vars
@export var Curent_Speed := 0.0
@export var Jump_Velocity := 4.5
@export var Walking_Speed := 5.0
@export var Crouching_Speed := 2.0
@export var Sprinting_Speed := 8.0
@export var Look_Sens := 0.006
@export var gravity = 12
@export var Lerp_Speed := 10.0
@export var air_lerp_speed = 0.01
#onready vars
@onready var standing_collision: CollisionShape3D = %"Standing Collision"
@onready var crouching_collision: CollisionShape3D = %"Crouching Collision"
@onready var head: Node3D = $head
@onready var eyes: Node3D = $head/eyes
@onready var crouching_collision_check: RayCast3D = $"Crouching Collision/Crouching collision check"
#Non-export vars
var Motion_Dir := Vector3(0,0,0)
var Crouching_Head_Position := Vector3(0, -0.1, 0)
var Standing_Head_Position := Vector3(0, 0.75, 0)
var is_walking = false
var is_sprinting = false
var is_crouching = false
var is_sliding = false
var Sliding_Timer := 0
var Sliding_Timer_Max := 1
var Sliding_Dir := Vector2.ZERO
var Sliding_Speed := 10
func _unhandled_input(event):
if event is InputEventMouseButton:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
elif Input.is_action_just_pressed("ui_cancel"):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
if event is InputEventMouseMotion:
self.rotate_y(-event.relative.x * Look_Sens)
head.rotate_x(-event.relative.y * Look_Sens)
head.rotation.x = clamp(head.rotation.x, deg_to_rad(-90), deg_to_rad(90))
func handle_ground_physics(delta):
var Input_Dir = Input.get_vector("Left", "Right", "Forward", "Backward").normalized()
if Input.is_action_pressed("Crouch") or is_sliding == true:
if is_on_floor():
Curent_Speed = Crouching_Speed
head.position.y = lerp(head.position.y, Crouching_Head_Position.y, Lerp_Speed * delta)
standing_collision.disabled = true
crouching_collision.disabled = false
if is_sprinting == true and Input_Dir != Vector2.ZERO:
is_sliding = true
Sliding_Timer = Sliding_Timer_Max
Sliding_Dir = Input_Dir
is_crouching = true
is_walking = false
is_sprinting = false
elif !crouching_collision_check.is_colliding():
standing_collision.disabled = false
crouching_collision.disabled = true
head.position.y = lerp(head.position.y, Standing_Head_Position.y, Lerp_Speed * delta)
if Input.is_action_pressed("Sprint"):
Curent_Speed = Sprinting_Speed
is_sprinting = true
is_crouching = false
is_walking = false
else:
Curent_Speed = Walking_Speed
is_sprinting = false
is_crouching = false
is_walking = true
if is_sliding == true:
Sliding_Timer -= delta
if Sliding_Timer <= 0:
is_sliding = false
print("sliding_finished")
Motion_Dir = lerp(Motion_Dir, (transform.basis * Vector3(Input_Dir.x, 0, Input_Dir.y)).normalized(), Lerp_Speed * delta)
if not is_on_floor():
if Input_Dir != Vector2.ZERO:
Motion_Dir = lerp(Motion_Dir, (transform.basis * Vector3(Input_Dir.x, 0, Input_Dir.y)).normalized(), delta * air_lerp_speed)
if Motion_Dir:
velocity.x = Motion_Dir.x * Curent_Speed
velocity.z = Motion_Dir.z * Curent_Speed
else:
velocity.x = move_toward(velocity.x, 0, Curent_Speed)
velocity.z = move_toward(velocity.z, 0, Curent_Speed)
if is_sliding == true:
Motion_Dir = (transform.basis * Vector3(Sliding_Dir.x, 0, Sliding_Dir.y)).normalized()
is_crouching = false
if is_sliding == true:
velocity.x = Motion_Dir.x * (Sliding_Timer) * Sliding_Speed
velocity.z = Motion_Dir.z * (Sliding_Timer) * Sliding_Speed
if is_sliding == true:
head.rotation.z = lerp(head.rotation.z, -deg_to_rad(7.0), delta * Lerp_Speed)
else:
head.rotation.z = lerp(head.rotation.z, -deg_to_rad(0), delta * Lerp_Speed)
if Input.is_action_just_pressed("Jump") and is_on_floor():
velocity.y = Jump_Velocity
pass
func handle_air_physics(delta):
if not is_on_floor():
velocity.y -= gravity * delta
func _physics_process(delta):
handle_air_physics(delta)
handle_ground_physics(delta)
move_and_slide()