I have the very same problem with another project. And once again I am stuck…
Issue: If the player pressed the opposite direction of the wall right before colliding with it, the “climb” animation is on the wrong side. It does not occur if the player jump and holds the direction in the same direction of the wall. It happens in both the fall and jump state.
Here are the revelant scripts:
input_handler.gd =
extends Node
@onready var jump_buffer_timer = $JumpBufferTimer
var x = 0
var jump_pressed = false
var jump_just_pressed = false:
get:
return jump_just_pressed
set(value):
jump_just_pressed = value
if value: jump_buffer = true
var jump_buffer:
get:
return not jump_buffer_timer.is_stopped()
set(value):
if value: jump_buffer_timer.start()
else: jump_buffer_timer.stop()
func update():
x = Input.get_axis("btn_left", "btn_right")
jump_just_pressed = Input.is_action_just_pressed("btn_jump")
jump_pressed = Input.is_action_pressed("btn_jump")
player.gd =
extends CharacterBody2D
class_name Player
@onready var fsm = $FSM
@onready var sprite = $AnimatedSprite2D
@onready var input = $InputHandler
const AIR_MULTIPLIER = 0.7
const MAX_SPEED = 90.0
const ACCELERATION = 900.0
const JUMP_GRAVITY = 900.0
const FALL_GRAVITY = 500.0
const TERMINAL_VELOCITY = 600.0
var last_direction = 1
var current_direction = 1
# direction = the direction that the player is facing
var direction :
get: return direction
set(value):
if value == 0 or value == direction: return
direction = value
sprite.flip_h = value == -1
func _ready():
fsm.change_state("idle")
func _physics_process(delta):
input.update()
fsm.physics_update(delta)
if is_on_floor():
# Disable collision with objects on layer 9
set_collision_mask_value(9, false)
else:
# Enable collision with objects on layer 9
set_collision_mask_value(9, true)
# Update last_direction based on current_direction
last_direction = current_direction if input.x == 0 else input.x
player_base_state.gd =
extends State
class_name PlayerBaseState
var input:
get: return object.input
func play(animation):
object.sprite.play(animation)
func accelerate(delta, direction = input.x):
var mult = Player.AIR_MULTIPLIER if not object.is_on_floor() else 1.0
object.velocity.x = move_toward(object.velocity.x, Player.MAX_SPEED * direction, Player.ACCELERATION * mult * delta)
func apply_gravity(delta):
var g = Player.JUMP_GRAVITY if fsm.current_state == "jump" else Player.FALL_GRAVITY
object.velocity.y = move_toward(object.velocity.y, Player.TERMINAL_VELOCITY, g * delta)
func move(delta, apply_g, update_direction = true, direction = input.x):
accelerate(delta, direction)
if apply_g: apply_gravity(delta)
if update_direction: object.direction = direction
object.move_and_slide()
player_climb_state.gd =
extends PlayerBaseState
func enter():
play("climb")
func physics_update(delta):
# Ensure the player is pressing jump and moving away from the wall
if input.jump_just_pressed and object.input.x != 0 and object.input.x != object.direction:
change_state("jump")
player_fall_state.gd =
extends PlayerBaseState
@onready var coyote_timer = $CoyoteTimer
func enter():
play("fall")
if fsm.previous_state != "jump":
coyote_timer.start()
func physics_update(delta):
move(delta, true)
if not coyote_timer.is_stopped() && input.jump_just_pressed:
change_state("jump")
elif object.is_on_floor():
if input.jump_buffer:
change_state("jump")
elif input.x == 0:
change_state("idle")
else:
change_state("run")
elif object.is_on_wall():
change_state("climb")
player_jump_state.gd =
extends PlayerBaseState
var variable_jump_height
func enter():
play("jump")
object.velocity.y = -300
object.velocity.x += input.x * Player.MAX_SPEED
variable_jump_height = false
input.jump_buffer = false
func physics_update(delta):
move(delta, true)
if not variable_jump_height and not input.jump_pressed:
variable_jump_height = true
if object.velocity.y <= 0:
object.velocity.y /= 2
if object.velocity.y >= 0:
change_state("fall")
elif object.is_on_wall():
change_state("climb")
Video of the issue: https://youtu.be/rJqrBqgez3s
Thank you in advance! I am sure the answer is obvious but I tried and tried…