With test_motion
I do not recommend handling this with the RigidBody2D
collisions because not every collision means it is on the ground (e.g. could be hitting a wall or ceiling).
However, there is another way: you can use test_motion
. It returns true if a movement would result in a collision (without actuallyu moving, of course).
So use test_motion
downwards, if it detects a collision, it means the RigidBody2D
is on the ground:
if Input.is_action_just_released("ui_up") and self.test_motion(Vector2(0, 1), false):
apply_central_impulse(Vector2(0,-1000))
With RayCast2D
Another simple setup is using RayCast2D
instead. Position it to extend downwards from the the bottom of the CollisionShape2D
or CollisionPolygon2D
of the RigidBody2D
. Make sure the RayCast2D
is enabled. Then you can check if the RayCast2D
is colliding to decide if the RigidBody2D
can jump:
if Input.is_action_just_released("ui_up") and $RayCast2D.is_colliding():
apply_central_impulse(Vector2(0,-1000))
Consider that with the above method, if the RayCast2D
fail to detect something, the RigidBody2D
won't be able to jump. For example, if the RayCast2D
is centered, but the RigidBody2D
is only partially on the ground, such that the RayCast2D
hits nothing.
With Area2D
Another alternative is to use an Area2D
instead of a RayCast2D
. Which has the advantage of having its own CollisionShape2D
or CollisionPolygon2D
. You will need to keep count of bodies that enter or exist the Area2D
:
var on_ground := 0
func _on_Area2D_body_entered(body: Node) -> void:
on_ground += 1
func _on_Area2D_body_exited(body: Node) -> void:
on_ground -= 1
And of course, use that in your check to jump:
if Input.is_action_just_released("ui_up") and on_ground > 0:
apply_central_impulse(Vector2(0,-1000))
Finally I remind you that you have collision layers and collision masks. Using a RayCast2D
or an Area2D
would allow you to set a different mask than the one the RigidBody2D
uses. Which is a way to specify that not all things that the RigidBody2D
collides with, are things from which it can jump.
I find Area2D
to be more reliable and versatile. However, it is more work to setup.