Slide on Crouching Godot 3.1.1 stable

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

Hi,
I know the question has been asked about a year ago but I don’t really want to reopen an old thread. Things may have changed with Godot 3.1 and to be honest I don’t understand how to implement the answer.

I am doing a 2D game and I try to add a slide function to my player.
I want my slide function to

  • stop responding to Input
  • move following game physics to X position
  • resume the input control.

So far I can only teleport to a specific location or move while in sliding position.

This is my code:

extends KinematicBody2D

const KUNAI = preload("res://scenes/Kunai.tscn")

var direction = 1

var camera_top = 0
var camera_left = 0
var camera_right = 4416
var camera_bottom = 1664 
var camera_position = 25


var is_attacking = false
var is_running = false
var is_sliding = false

export var snap = false
export var move_speed = 350
export var jump_force = 550
export var gravity = 900 
export var slop_slide_threshold = 60
var velocity = Vector2()
var destination = Vector2()

func _ready():
	connect("finished", self, "on_finished")
	$camera2D.limit_top    = camera_top
	$camera2D.limit_left   = camera_left
	$camera2D.limit_right  = camera_right
	$camera2D.limit_bottom = camera_bottom	
	set_process(true)
	pass

func  _physics_process(delta):
	
	## Move ##
	var direction_x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
	velocity.x = direction_x * move_speed
	print("velocity.x: "+str(velocity.x))
	print("direction_x: "+str(direction_x))
	
	## Running ##
	if Input.is_action_pressed("ui_focus_prev") && velocity.x !=0:
		is_running = true
		if snap == true && is_sliding == false:
			move_speed = 700
		$sprite.frames.set_animation_speed("Run", 25)
		camera_position = 35
	else:
		is_running = false
		if snap == true && is_sliding == false:
			move_speed = 350
		$sprite.frames.set_animation_speed("Run", 15)
		camera_position = 20
		
	## Slide ##
	if is_running and Input.is_action_just_pressed("ui_down"):
		is_sliding = true
		move_speed = 1000
		$collisionshape2D.rotation_degrees = 90
	if Input.is_action_just_released("ui_down"):
		is_sliding = false
		if $collisionshape2D.rotation_degrees == 90:
			position.y = position.y-($collisionshape2D.get_shape().height/2)
			$collisionshape2D.rotation_degrees = 0

	## Jump ##
	if Input.is_action_just_pressed("ui_select") and snap :
		velocity.y = -jump_force
		snap = false
		# insert jump sound
		
	## Set Gravity ##	
	velocity.y += gravity * delta
		
	## apply movement ##
	var snap_vector = Vector2(0, 32) if snap else Vector2()
	velocity = move_and_slide_with_snap(velocity, snap_vector, Vector2.UP, slop_slide_threshold)	

	## prevent jumping ##
	if is_on_floor() and not is_sliding and (Input.is_action_just_released("ui_right") or Input.is_action_just_released("ui_left")):
		velocity.y = 0
	
	## enable snap when landing ##
	var just_landed = is_on_floor() and not snap
	if just_landed:
		snap = true
	
	update_animation(velocity)

func update_animation(velocity: Vector2):
	var animation = "Idle"

	if abs(velocity.x) > 10.0:
		$sprite.flip_h = velocity.x < 0
		if is_sliding:
			animation = "Slide"
		else:
			animation = "Run"
	
	if not is_on_floor():
		animation = "Jump" if velocity.y < 0 else "Fall"
	
	if $sprite.animation != animation:
		$sprite.play(animation)

Thank you

I was searching for a workaround and I found out the hard way, the variable in a while loop will not update inside a _physics_process(delta).

In the same process of tough, I was trying to implement a wall jump using this:

## Wall Jump ##
if Input.is_action_just_pressed("ui_select") &&  is_on_wall() :
	velocity.y = -jump_force
	velocity.x =  run_speed * -1 
	snap = false
	while velocity.y < 0: 
		print(str(velocity.y))
		velocity.x =  10 * direction
		velocity = move_and_slide(velocity, Vector2.UP)
		update_animation(velocity)

That code doesn’t even print my velocity.y once. How can I temporarily ignore the input and perform a fluid movement inside a _physics_process ?

TheLastCayen | 2019-07-25 08:12

:bust_in_silhouette: Reply From: TheLastCayen

I don’t know if it’s the best practice, but I found a way and it may help some.
I am using a variable to skip the input while I perform my scripted action.
This is a part of my code:

var is_scripted_movement = false

func  _physics_process(delta):
	
	update_component()
	
	## quit game even during scripted animation ##
	if Input.is_action_pressed("ui_cancel"):
		get_tree().quit()
	if is_scripted_movement:
		
		## scripted wall jump ##
		if not snap && (is_on_wall() or velocity.y >= -gravity/5.5):
			is_scripted_movement = false
			
	## scripted slide ##
	if is_sliding:
		if is_on_wall():
			direction = -sign(direction)
			update_component()
			velocity.x = run_speed * direction
			print("after: " + str(direction))
		if not is_on_floor():
			$collisionshape2D.rotation_degrees = 0
			is_scripted_movement = false
		if not $rc_left_up.is_colliding() && not $rc_right_up.is_colliding():
			if (direction == 1 && position.x >= scripted_position_end.x) or (direction == -1 && position.x <= scripted_position_end.x):
				is_sliding = false
				if is_on_floor():
					position.y = position.y-($collisionshape2D.get_shape().extents.y)
				$collisionshape2D.rotation_degrees = 0
				is_scripted_movement = false

	## input movement ##
	else:

		### insert character input here ####

		## Slide ##
		if is_on_floor() && (is_running && Input.is_action_just_pressed("ui_down")) or (Input.is_action_just_pressed("ui_select") && Input.is_action_pressed("ui_down")):
			velocity.x =  run_speed * direction
			is_sliding = true
			$collisionshape2D.rotation_degrees = 90
			position.y = position.y+($collisionshape2D.get_shape().extents.y/2)
			scripted_position_end.x = position.x + ((64*5)*direction)
			is_scripted_movement = true

		## Wall Jump ##
		if Input.is_action_just_pressed("ui_select") &&  is_on_wall() && not is_on_floor() :
			direction = -sign(direction)
			update_component()
			velocity.y = -jump_force
			velocity.x =  run_speed * direction
			snap = false
			jump_release = false
			is_scripted_movement = true
		if Input.is_action_just_released("ui_select"): 
			jump_release = true

	## Set Gravity ##	
	velocity.y += gravity * delta
			
	## apply movement ##
	var snap_vector = Vector2(0, 32) if snap else Vector2()
	velocity = move_and_slide_with_snap(velocity, snap_vector, Vector2.UP, slop_slide_threshold)