Crouching system

4.4
I am having trouble with a crouching system. I am currently using a ShapeCast2D to check if anything is colliding but i am using a while loop and it should terminate but my game keeps crashing when i run it so i am pretty sure that it is the while loop but it won’t terminate so here’s the code.

extends CharacterBody2D
var is_crouching = false
var can_uncrouch = true
var can_crouch = true
var jump_count = 0
var speed = 600
var jump_velocity = -600

func _process(_delta: float) → void:
$LightHolder.look_at(get_global_mouse_position())
if $UncrouchChecker:
print(“fjfjfjfjfgjfjfjfhfjfjfhgjfhgjfhgjfhgjfhgjfhgjfhgjfhg”) # Ignore this
#while $UncrouchChecker.collide_with_bodies(StaticBody2D):
can_uncrouch = false
can_uncrouch = true

if is_crouching == false:
	$Pupil/EyeAnimations.play("Looking")
else:
	$Pupil/EyeAnimations.stop(false)

if Input.is_action_pressed("LeftClick"):
	$LightHolder.visible = true
else:
	$LightHolder.visible = false

func _physics_process(delta: float) → void:
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta

if Input.is_action_pressed("ui_accept") and is_on_floor(): #Jump
	velocity.y = jump_velocity
	jump_count = 1
elif Input.is_action_just_pressed("ui_accept") and jump_count == 1: # Double Jump
	velocity.y = jump_velocity
	jump_count = 0

# Handles crouching
if Input.is_action_pressed("ui_down"):  # Crouch
	is_crouching = true
	speed = 300
	$Body.scale.y = 0.145
	$Pupil.scale.y = 0.145
	$Collision.scale.y = 0.748

elif Input.is_action_just_released("ui_down") and can_uncrouch == true: # Uncrouch
	is_crouching = false
	speed = 600
	$Body.scale.y = 0.39
	$Pupil.scale.y = 0.376
	$Collision.scale.y = 1.728

var direction := Input.get_axis("ui_left", "ui_right")
if direction:
	velocity.x = direction * speed
else:
	velocity.x = move_toward(velocity.x, 0, speed)
if Input.is_action_pressed("ui_left") and is_crouching == false:
	$PlayerAnimations.play("Left")
elif Input.is_action_pressed("ui_right") and is_crouching == false:
	$PlayerAnimations.play("Right")
else:
	$PlayerAnimations.stop(false)
move_and_slide()

and here’s a screenshot of my main issue with this system


the player keeps getting stuck in the walls and floor when you uncrouch in a crouching area

So once this is true, it will never escape the while loop. Rewrite this _process without a while loop. All you need to do is in this frame, is it touching a body? You do not need a while loop at all.

Create a function that returns true or false to set the value of can_uncrouch. Just a single test, are we currently able to uncrouch or not, ie, are we currently touching any bodies. No need for a whlile loop at all. The _process is your while loop already. Every frame it will test if you are crouched, if you can uncrouch or not.

2 Likes

Is this line normally uncommented? Also, is $UncrouchChecker a regular ShapeCast2D? (i.e. you didn’t extend it with any custom code?)

The documentation does mention a collide_with_bodies, but it’s a property, not a method, and cannot be used the way your code does.

If you absolutely have to use a while loop inside _process, make sure that whatever code is inside the loop can also terminate the loop or break out of it somehow.

(Also, please post your code as preformatted text. i.e. enclose it with three backticks (```).)

1 Like

Yeah, it is impossible to work out what is really going on here.

??? who knows!

PS Surely it would have been quicker to delete the comment than write # ignore this

i tried to do the tick thing but i couldnt get it working cuz i used apostrophes instead
and yes uncrouch checker is my shapecast and that should be uncommented and i am also very new to godot and what i need it to do is to keep the player crouched while it is underneath an object

So you do not need a while loop. While crouched do a single check for ‘are there things stopping me standing up’. If there are, can_uncrouch is false, else can_uncrouch is true. Then that should fix it.