• 2D
  • How do you ground check using raycasting?

I've heard using raycasts to check for a floor is far more efficient than using "is_on_floor". How do I achieve that?

I can make raycasts and attach them to the player but getting them to work in GDscript I don't know how to do. Big thanks in advance

Thanks, I'll give this a try in a while. It looks logical so I've got my hopes up.

Alright that didn't work. Still looking for answers, I'll post my code below:

extends KinematicBody2D

const UP = Vector2(0, -1)

var velocity = Vector2()
var move_speed = 32 * 8
var gravity = 600
var jump_velocity = -250
var speed_y = 0
var is_grounded
onready var ground_ray = get_node("ground_ray")


func _ready():
	pass


func _input(event):
	if event.is_action_pressed("jump") && ground_ray.is_colliding():
		velocity.y = jump_velocity


func _physics_process(delta):
	velocity.y += gravity * delta
	_get_input()
	velocity = move_and_slide_with_snap(velocity, UP)
	_flip()



func _get_input():
	var move_direction = -int(Input.is_action_pressed("moveleft")) + int(Input.is_action_pressed("moveright"))
	velocity.x = lerp(velocity.x, move_direction * move_speed, 0.2)

func _flip():
	if Input.is_action_pressed("moveleft"):
		get_node("Body/playerSprite").scale.x = -1
	elif Input.is_action_pressed("moveright"):
		get_node("Body/playerSprite").scale.x = 1

hopeful a knight in shining armour comes along :)

Looking at the code posted, something like this should hopefully work, so long as the ground raycast can reach the ground and is setup correctly:

extends KinematicBody2D

const UP = Vector2(0, -1)

var velocity = Vector2()
var move_speed = 32 * 8
var gravity = 600
var jump_velocity = -250
# Track whether the jump action is down with this variable:
var input_jump_down = false
var speed_y = 0
var is_grounded = false
onready var ground_ray = get_node("ground_ray")

func _ready():
	pass

func _physics_process(delta):
	_update_grounded()
	velocity.y += gravity * delta
	_get_input()
	
	if (input_jump_down == true and is_grounded = true):
		velocity.y = jump_velocity
		is_grounded = false
	
	velocity = move_and_slide_with_snap(velocity, UP)
	_flip()

func _update_grounded():
	# Make sure we have the latest raycast data
	ground_ray.force_raycast_update()
	# Update the is_grounded variable
	is_grounded = ground_ray.is_colliding()

func _get_input():
	var move_direction = -int(Input.is_action_pressed("moveleft")) + int(Input.is_action_pressed("moveright"))
	velocity.x = lerp(velocity.x, move_direction * move_speed, 0.2)
	
	if (Input.is_action_pressed("jump")):
		input_jump_down = true
	else:
		input_jump_down = false

func _flip():
	if Input.is_action_pressed("moveleft"):
		get_node("Body/playerSprite").scale.x = -1
	elif Input.is_action_pressed("moveright"):
		get_node("Body/playerSprite").scale.x = 1

Hopefully this works and helps! :smile: The only really big change I made is moving checking if the ground_ray is colliding to _physics_process so it is in sync with the physics engine, and move jump detection to _get_input instead of _input.

(Side note: I edited your post so the code is formatted correctly)

Thanks for putting your time into this. Lol I need some sleep now but I'll try this tomorrow and tell you how it goes. Thanks again