Godot Version
4.3
Question
i have followed a tutorial on a movement system in godot and changed it to suit my needs and also added some other things, one of those things are coyote time. when i have double jumps disabled it works just fine but when double jumps are active, instead of getting a free coyote jump when you’re falling off a ledge, it uses your double jump. i tried everything from making canDjump=false whenever you can coyote jump but i got nothing, all my attemps either resulted in infinite double jumps or one jump taking the player to the moon and inverting their gravity.
here is my code, i’ve attempted to make it readable…lol
(there’s also this thing where the dash curve doesnt do much…would be a nice bonus if someone got it but eh, im fine with how it is right now)
extends CharacterBody2D
#unlocks
@export var Wall_jumpU:bool=false
@export var DashU:bool=false
@export var GroundPoundU:bool=false
@export var DoubleJumpsU:bool=false
#speed stuff
@export var speed = 200
@export_range(0,1) var acceleration = 0.1
@export_range(0,1) var deceleration = 0.1
#jump stuff
@export var jump_force = -400.0
@export_range(0,1) var decelerate_on_jump_release = 0.5
@export var jump_buffer_time = 0.1
#double jump stuff
@export var Double_jump_force= -300
@export var Djumps= 1
#coyote time stuff
@export_range(0,1) var coyote_time=0.15
@onready var coyote_timer: Timer = $"Coyote Timer"
#wall jump stuff
@export var wall_jump_H_force = 300
@export var wall_jump_V_force = -500
#dash stuff
@export var dash_speed = 1000
@export var dash_distance = 100
@export var dash_curve: Curve
@export var dash_cooldown = 1.0
#ground pound stuff
@export var Gpound_speed = 1000.0
var is_touching_left_wall:bool=false
var is_touching_right_wall:bool=false
var is_dashing=false
var dash_start_position=0
var dash_direction=0
var dash_timer=0
var timesJumped=0
var CanDjump:bool=true
var JumpAvailable:bool=true
var jump_buffer:bool=false
var canCjump=false
func _physics_process(delta: float) -> void:
# Add the gravity.
if not is_on_floor():
if JumpAvailable:
if coyote_timer.is_stopped():
canCjump=true
coyote_timer.start(coyote_time)
else:
velocity-= get_gravity() * delta
velocity += get_gravity() * delta
# Handle jump and Coyote Time.
if Input.is_action_just_pressed("jump"):
if JumpAvailable:
Jump()
else:
jump_buffer=true
get_tree().create_timer(jump_buffer_time).timeout.connect(_on_jump_buffer_timeout)
if not is_on_floor() and canCjump:
if Input.is_action_just_pressed("jump"):
Jump()
# Double Jump handling
if Input.is_action_just_pressed("jump") and not is_on_floor() and DoubleJumpsU==true and CanDjump==true and not is_on_wall():
velocity.y = Double_jump_force
timesJumped+=1
if timesJumped==Djumps:
CanDjump=false
if is_on_floor():
timesJumped=0
JumpAvailable=true
coyote_timer.stop()
CanDjump=true
if jump_buffer:
Jump()
jump_buffer=false
if is_on_wall() and Wall_jumpU==true:
# Check which side
var wall_normal = get_wall_normal()
is_touching_left_wall = is_on_wall() and wall_normal.x > 0
is_touching_right_wall = is_on_wall() and wall_normal.x < 0
else:
is_touching_left_wall = false
is_touching_right_wall = false
if Input.is_action_just_pressed("jump"):
if is_touching_left_wall:
velocity.x = wall_jump_H_force
velocity.y = wall_jump_V_force
elif is_touching_right_wall:
velocity.x = -wall_jump_H_force
velocity.y = wall_jump_V_force
if Input.is_action_just_released("jump") and velocity.y < 0:
velocity.y *= decelerate_on_jump_release
# Get the input direction and handle the movement/deceleration.
var direction := Input.get_axis("left", "right")
if direction:
velocity.x = move_toward(velocity.x, direction * speed, speed * acceleration)
else:
velocity.x = move_toward(velocity.x, 0, speed * deceleration)
if direction and (is_on_floor() or is_on_wall()):
$Sprite2D/WalkParticles.emitting=true
else:
$Sprite2D/WalkParticles.emitting=false
#dash activation
if Input.is_action_just_pressed("dash") and direction and not is_dashing and dash_timer <=0 and DashU:
is_dashing = true
dash_start_position = position.x
dash_direction = direction
dash_timer = dash_cooldown
#actual dash
if is_dashing==true:
var current_distance= abs(position.x - dash_start_position)
if current_distance >= dash_distance or is_on_wall():
is_dashing=false
else:
velocity.x = dash_direction * dash_speed * dash_curve.sample(current_distance / dash_distance)
velocity.y = 0
#dash timer management
if dash_timer > 0:
dash_timer-=delta
move_and_slide()
#Gpound
if (Input.is_action_just_pressed("down") or Input.is_action_just_pressed("Gpound")) and not is_on_floor():
velocity.y=Gpound_speed
func Coyote_timeout():
canCjump=false
JumpAvailable=false
func Jump()->void:
velocity.y = jump_force
JumpAvailable=false
func _on_jump_buffer_timeout() ->void:
jump_buffer=false
(sorry to whoever mustered up the patience to read all of that…)