I have a KinematicBody2D (player) and an Area2D (ladder). With the following code I get clean enter and exit events that happen as the player touches and leaves the Area2D object e.g. touch Area2D and a single "enter" prints. Move back and a single "exit" prints.
func _on_Ladder_body_entered(body):
if body.name == "Hero":
print("enter")
func _on_Ladder_body_exited(body):
if body.name == "Hero":
print("exit")
with this code things go wrong:
func _on_Ladder_body_entered(body):
if body.name == "Hero":
set_collision_layer_bit(0, false)
print("enter")
func _on_Ladder_body_exited(body):
if body.name == "Hero":
set_collision_layer_bit(0, true)
print("exit")
I get an entered event immediately followed by an exit event as soon as the player touches the Area2D. What am I doing wrong? Thanks! Godot version 3.4.2
Godot is doing what you are telling it to do.
The call set_collision_layer_bit(0, false)
would be disabling the collision between the KinematicBody2D
and the Area2D
which means they would no longer be colliding. And since they stop colliding, you get a "body_exited"
signal.
I want to turn off collisions so the player can pass the object and re-enable them when he passes and leaves the Area2D object
The Area2D
do not stop physics bodies (StaticBody2D
, KinematicBody2D
, RigidBody
). There must be something else doing that. For example, if you added a StaticBody2D
to the ladder, or made it with a TileMap
where the tiles have collision, those could stop your KinematicBody2D
.
I think the simplest approach would be to put the Area2D
in a different collision layer, so you can disable the collision that stops the KinematicBody2D
without disabling the Area2D
.
Other options to disable collisions include:
CollisionPolygon2D
or CollisionShape2D
by setting disabled
to true
. Note: you cannot to do this while Godot is resolving collision response. To avoid that, use set_deferred
to change the value of disabled
.add_collision_exception_with
. Use remove_collision_exception_with
to remove the exception. This is a more fine grained tool that should be used sparingly (if you are adding lots of exception, prefer using collision layers and masks).Addendum: An option for the TileMap
is to have two version of the tile, one with the collision and one without it. And the swap them in runtime with set_cell
. However, consider using a scene instead. In fact, you might want to set the cells in the designer and replace them with actual scenes in runtime. See How to use SCENES in a TILEMAP(And 9 MORE TRICKS) | Godot Engine. You may even do it only when the player gets nearby, see How to create large Sidescrolling Map in Godot?.