How to let the player bounce off a wall while wall jumping

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Kroklark

I have a code where i can do much movement with a Kinematic body 2d such as rolling, running, jumping and *wallsliding
right now if im wall sliding and i press the jump button , the player jump straitght up , and can jump al the way up of a wall, i wanna make that if the player jumps while wall sliding instead of jumping straight he jumps to the left , like Hollow Knight etc…
im sorry for asking such a question with such a long code but i really can’t figure it out , im new to game dev , thanks for the ones who are going to start an adventure reading that code xD

Here’s my super messy code! :

extends KinematicBody2D

const WALL_JUMP_COOLDOWN := 0.3
const WALL_SLIDE_GRAVITY_MULTIPLIER := 0.8

var velocity := Vector2.ZERO

export var move_speed = 200.0
export var jump_height : float
export var jump_time_to_peak : float
export var jump_time_to_descent: float
export var wall_jump_height = -500
export var wall_jump_push = 400

onready var jump_velocity : float = ((2.0 * jump_height) / jump_time_to_peak) * -1.0
onready var jump_gravity : float = ((-2.0 * jump_height) / (jump_time_to_peak * jump_time_to_peak)) * -1.0
onready var fall_gravity : float = ((-2.0 * jump_height) / (jump_time_to_descent * jump_time_to_descent)) * -1.0

var coyoteTimer = true
var jumpWasPressed = false
var direction = 1
var direction2 = 0
var just_wall_jumped := false

enum state {
IDLE,
RUNNING,
ROLLING,
JUMP,
FALL,
ATTACK,
WALL
}

onready var player_state = state.IDLE

func update_animation(anim):
if velocity.x < 0 :
$Sprite.flip_h = true
if velocity.x > 0 :
$Sprite.flip_h = false
match(anim):
state.IDLE:
$AnimationPlayer.play(“Idle”)
state.RUNNING:
$AnimationPlayer.play(“Run”)
state.ROLLING:
$AnimationPlayer.play(“Rolling”)
yield($AnimationPlayer,“animation_finished”)
player_state = state.IDLE
state.JUMP:
$AnimationPlayer.play(“Jumping”)
state.FALL:
$AnimationPlayer.play(“Falling”)
state.WALL:
$AnimationPlayer.play(“WallSlide”)

func _physics_process(delta):
handle_input()
set_player_state()

velocity.y += get_gravity() * delta
if is_on_floor():
	coyoteTimer = true
	if jumpWasPressed == true:
		jump()
	
if player_state == state.WALL:
	velocity.y *= WALL_SLIDE_GRAVITY_MULTIPLIER



if !is_on_floor():
	coyoteTime()
	

if Input.is_action_just_released("ui_up") && velocity.y < 0 :
	velocity.y = 0


velocity = move_and_slide(velocity, Vector2.UP)

func handle_input():

var is_jump_halted := Input.is_action_just_released("ui_up") and velocity.y < 0.0
direction2 = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left") 
if just_wall_jumped == false :
	velocity.x = direction2 * move_speed


if Input.is_action_just_pressed("ui_up") and (is_on_floor() or player_state == state.WALL):
	if player_state == state.WALL:
		$WallJumpTimer.start(WALL_JUMP_COOLDOWN)
		just_wall_jumped = true
		if Input.is_action_pressed("ui_right") or Input.is_action_just_released("ui_right"):
			velocity.y = -move_speed
		elif Input.is_action_pressed("ui_left") or Input.is_action_just_released("ui_left"):
			velocity.y = move_speed
	velocity.y = jump_velocity

if is_jump_halted:
	velocity.y = 0

func set_player_state():
if player_state != state.ROLLING and player_state != state.ATTACK:
velocity.x = get_input_velocity() * move_speed
set_direction()
if velocity.x == 0:
player_state = state.IDLE
if velocity.x != 0 and Input.is_action_just_pressed(“roll”):
player_state = state.ROLLING

	elif velocity.x != 0:
		player_state = state.RUNNING


	if player_state != state.ROLLING:
		if Input.is_action_just_pressed("ui_up"):
			jumpWasPressed = true
			rememberJumpTime()
			if coyoteTimer == true:
				jump()
				player_state = state.JUMP

if !is_on_floor():
	if velocity.y < 0:
		player_state = state.JUMP
	else:
		if is_on_wall() and \
				(Input.is_action_pressed("ui_left") and !Input.is_action_pressed("ui_right") or \
				(Input.is_action_pressed("ui_right") and !Input.is_action_pressed("ui_left"))) :
			player_state = state.WALL
		else:
			player_state = state.FALL
update_animation(player_state)

func set_direction():
direction = 1 if not $Sprite.flip_h else -1
$WallChecker.rotation_degrees = 90 * -direction

func is_near_wall():
return $WallChecker.is_colliding()

func get_gravity() → float:
return jump_gravity if velocity.y < 0.0 else fall_gravity

func jump():
velocity.y = jump_velocity

func get_input_velocity() → float:
var horizontal := 0.0

if Input.is_action_pressed("ui_left"):
	horizontal -= 1.0
elif Input.is_action_pressed("ui_right"):
	horizontal += 1.0
return horizontal

func coyoteTime():
yield(get_tree().create_timer(.1), “timeout”)
coyoteTimer = false
pass

func rememberJumpTime():
yield(get_tree().create_timer(.1), “timeout”)
jumpWasPressed = false
pass

func _on_WallJumpTimer_timeout() → void:
just_wall_jumped = false

:bust_in_silhouette: Reply From: Coconut35

You basically need to know if the wall is on the left or on the right of the player (with Raycasts for exemple) and then add velocity in the other direction.
This video explain it pretty well.

thanks a lot for the answer, in the end i did a finite state machine and now all works , thankssssssssssss

Kroklark | 2023-02-14 12:39