Godot Version
Godot 4.6.2
Question
I’m Trying to make a momentum based movement system but the crouch system always bugs
Whenever I slide, My character tends to get axis locked and starts sliding parallel to the nearest axis after entering the slide state and won’t go in my looking direction
Enters Slide State
Goes In The Desired Direction (Looking Direction) As Expected
But Then Gets Aligned to the nearest axis
If you share code, please wrap it inside three backticks or replace the code in the next block:
extends CharacterBody3D
enum State { IDLE,
MOVE,
SPRINT,
JUMP,
FALL,
SLIDE, }
@export_group("STATES")
@export var cur_state = State.IDLE
## PLAYER CAMERA ONREADY ##
@onready var neck = $Neck
@onready var camera_3d = $Neck/Camera3D
## CANVAS LAYER ONREADY ##
@onready var speed = $CanvasLayer/Speed
## TIMERS ONREADY ##
##JUMPBUFFER##
@onready var jumpbuffer = $Timers/JUMPBUFFER
## ABSTRACT VARIABLES ##
var direction: Vector3= Vector3(1,0,1)
## MOUSE SENSITIVITY ##
@export_group("MOUSE SENSITIVITY")
@export var mouse_sensi = 0.009
## PLAYER MOVEMENT VARIABLES (X-Z) ##
@export_group("MOVEMENT VAR (X-Z)")
######
@export var CUR_SPEED = 0.0
@export var use_speed = 0.0
######
@export var walk_speed = 12.0
@export var sprint_speed = 30.0
@export var slide_boost = 20.0
## ACCEL/DECEL ##
@export_group("ACCEL/DECEL")
@export var ground_accel = 100.0
@export var air_accel = 50.0
@export var decel = 80.0
@export var slide_decel = 10.0
## PLAYER MOVEMENT VARIABLES (Y) ##
@export_group("MOVEMENT VAR (Y)")
@export var JUMP_VELOCITY = 25.0
@export var gravity = -60.0
func _ready():
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _unhandled_input(event):
if event is InputEventMouseMotion:
rotate_y(-event.relative.x * mouse_sensi)
camera_3d.rotate_x(-event.relative.y * mouse_sensi)
camera_3d.rotation.x = clamp(camera_3d.rotation.x, deg_to_rad(-85), deg_to_rad(+80))
if event.is_action_pressed("escape") and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
elif event.is_action_pressed("escape") and Input.mouse_mode == Input.MOUSE_MODE_VISIBLE:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _physics_process(delta):
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta
if Input.is_action_just_pressed("jump"):
if is_on_floor():
change_state(State.JUMP)
elif not is_on_floor():
jumpbuffer.start()
if not jumpbuffer.is_stopped() and is_on_floor():
change_state(State.JUMP)
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
var input_dir = Input.get_vector("left", "right", "forward", "backward")
direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
var current_speed = Vector2(velocity.x, velocity.z).length()
match cur_state:
State.IDLE:
CUR_SPEED = 0.0
velocity.x = move_toward(velocity.x,CUR_SPEED, decel * delta)
velocity.z = move_toward(velocity.z,CUR_SPEED, decel * delta)
if direction:
if Input.is_action_just_pressed("sprint"):
change_state(State.SPRINT)
else:
change_state(State.MOVE)
elif not is_on_floor():
change_state(State.FALL)
State.MOVE:
CUR_SPEED = move_toward(current_speed, walk_speed, ground_accel * delta)
velocity.x = direction.x * CUR_SPEED
velocity.z = direction.z * CUR_SPEED
if Input.is_action_just_pressed("sprint"):
change_state(State.SPRINT)
elif direction == Vector3.ZERO:
change_state(State.IDLE)
elif not is_on_floor():
change_state(State.FALL)
State.JUMP:
if velocity.y <= 0.0 or Input.is_action_just_released("jump"):
change_state(State.FALL)
State.FALL:
if is_on_floor():
if direction:
change_state(State.SPRINT)
else:
change_state(State.IDLE)
State.SPRINT:
CUR_SPEED = move_toward(current_speed, sprint_speed, ground_accel * delta)
velocity.x = direction.x * CUR_SPEED
velocity.z = direction.z * CUR_SPEED
if Input.is_action_just_pressed("sprint"):
change_state(State.MOVE)
elif direction == Vector3.ZERO:
change_state(State.IDLE)
elif not is_on_floor():
change_state(State.FALL)
if Input.is_action_pressed("crouch_slide"):
change_state(State.SLIDE)
State.SLIDE:
velocity.x = move_toward(velocity.x, 0.0, slide_decel * delta)
velocity.z = move_toward(velocity.z, 0.0, slide_decel * delta)
if Input.is_action_just_released("crouch_slide"):
change_state(State.SPRINT)
if not is_on_floor():
change_state(State.FALL)
var flat_speed = Vector2(velocity.x, velocity.z).length()
speed.text = "Speed: " + str(snappedf(flat_speed, 0.1))
print(Vector2(velocity.x, velocity.z).length())
move_and_slide()
func change_state(to_state: State):
cur_state =to_state
match cur_state:
State.IDLE:
pass
State.MOVE:
pass
State.SPRINT:
pass
State.JUMP:
velocity.y += JUMP_VELOCITY
State.FALL:
pass
State.SLIDE:
velocity.x += direction.x * slide_boost
velocity.z += direction.z * slide_boost