Reputation: 121
I am trying to make a teleport part, so I need to detect when Body collides with area. I tried to use body_enter
/body_entered
and body_exit
/body_exited
, but I do not know how exactly they work and where do I need to insert them. Can I have example codes of using it?
My nodes path:
RigidBody
├ CollisionShape
├ MeshInstance
├ Area
├ ├ CollisionShape
Upvotes: 3
Views: 18393
Reputation: 40220
Scene tree structure
First of all, if you want two things to collide you probably want them to be siblings. Not one Node
child of the other. This is because Spatial
s are placed relative to their parent. Said another way: when an Spatial
moves, its children move with it.
Enable monitoring
Second, you want to make sure that the Node
that will detect the collision is able to do it. In the case of a RigidBody
and an Area
, the Area
will detect the RigidBody
, and for that it must have monitoring
to be true
This is the default. Thus, unless you have been messing with it, you need to do nothing.
Layers and masks
Third, you want the layers and masks to overlap. In particular, you want the collision_mask
of the Area
to have bits in common with the collision_layer
of the RigidBody
. By default, they come with the first bit set, so this is also satisfied by default unless you have been messing with it.
SIGNALS
Fourth, you need to connect the "body_entered"
signal of the Area
. You have two ways to do that:
Using the editor:
Have the Area
selected in the Scene panel (on the left by default), and then go to the Node panel (on the right by default) and then to the Signals tab.
There you should find "body_entered(body:Node)". Double click it. Or select it and then click the "Connect…" button at the bottom, or press enter.
Godot will ask you to select the Node
you will connect it to. You can connect it to any Node
on the same scene that has a script attached beforehand. I suggest to connect it to the Area
itself.
Godot will also allow you to specify the name of the method that will handle it (by default the name will be _on_Area_body_entered
).
Under "advanced" you can also add extra parameters to be passed to the method, whether or not the signal can/will wait for the next frame ("deferred"), and if it will disconnect itself once triggered ("oneshot").
By pressing the Connect button, Godot will connect the signal accordingly, creating a method with the provided name in the script of the target node if it does not exist.
From code:
To connect a signal from code you use the connect method. See also disconnect and is_connected.
So you can, use the connect
method to connect the "body_entered"
signal, like this:
func _ready() -> void:
connect("body_entered", self, "_on_Area_body_entered")
func _on_Area_body_entered(body:Node) -> void:
pass
This code is intended to work in a script attached to the Area
itself. It is also possible to call connect
from a Node
to another. Please note that we are passing the name of the method we want to connect as parameter to the connect
method, and thus it can be whatever you want.
The connect
method has optional parameters to specify extra parameters, or if you want the connection to be deferred or oneshot.
To reiterate: simply adding a method won't work, you need to connect the signal to it. And there is no special name for the method, it can have any name you choose.
With that done, the method should execute when the RigidBody
overlaps the Area
.
Upvotes: 6