Username008445
Username008445

Reputation: 1

godot gdscript crouching system not playing correctly

I am trying to add a crouching mechanic to my game, but it won't let me uncrouch at all.

    var crouch = false
    if Input.is_action_pressed("Crouch"):
        speed = CROUCHSPEED
        if !crouch:
            $AnimationPlayer.play("Crouch")
            crouch = true
    else:
        if crouch:
            var space_state = get_world_3d().direct_space_state
            var result = space_state.intersect_ray(PhysicsRayQueryParameters3D.create(position, position + Vector3(0,2,0), 1, [self]))
            if result.size() == 0:
                $AnimationPlayer.play_backwards("Crouch")
                crouch = false

I have tried everything that I could think of to solve it like playing the crouch animation backwards, but I don't know how to fix it.

Upvotes: 0

Views: 289

Answers (1)

Theraot
Theraot

Reputation: 40315

I'll trim out your code to highlight the issue:

    var crouch = false
    if Input.is_action_pressed("Crouch"):
        # ...
    else:
        if crouch:
            # ...

As you can see crouch starts false. So it does not enter in the conditional if crouch.

To be clear, here crouch is a local variable of the method where you write this code. When the aforementioned method is not executing, the crouch variable does not exist, and therefore cannot have a value. We say that the variable is scoped to the method.

To be more precise, if the method were executing multiple times (for example, if the method calls itself recursively, or if it was executed from multiple threads) each execution of the method would have its own local variable with its own value.


Ok, let us look at the first part of the code:

    var crouch = false
    if Input.is_action_pressed("Crouch"):
        speed = CROUCHSPEED
        if !crouch:
            $AnimationPlayer.play("Crouch")
            crouch = true

Again, crouch starts false. So if the action "Crouch" is pressed, it will always enter the conditional if !crouch. I don't that is what you meant.

Instead, you could to keep track of the crouching state with an instance variable (a.k.a field). Instance variables are scoped to the instance※ and thus will retain their value across multiple executions of your method.

So you would declare crouch outside of the method (the guideline is to do it before the methods, near the top of the file):

var crouch := false

※: For example the Node where the script is attached. More precisely each instance that has the script attached would have its own instance variable with its own value.


By the way, I don't see you change the value speed other than here:

    if Input.is_action_pressed("Crouch"):
        speed = CROUCHSPEED

I don't know how you handle that. You could do something like the following after the code you have shown:

    if crouch:
        speed = CROUCHSPEED
    else:
        speed = NORMALSPEED

Upvotes: 0

Related Questions