I need to know how I can change scenes in Godot 3.5 when the player touches another CollisionShape2D.

I've tried this:

extends Area2D

func _on_Area2D_body_entered(_body):

print() is to check if it has changed the scene and it did change the scene but it seems to change right from the start.

I also got this error:

Missing connected method '_on_Area2D_body_shape_entered' for signal 'body_shape_entered' from node 'World/Area2D' to node 'World/Area2D'

  • 1
    \$\begingroup\$ The error tells you Godot is looking for a method _on_Area2D_body_shape_entered that was connected to a signal, but the code you show has _on_Area2D_body_entered instead. I'm not sure how that happened, but I'm guessing it is an incorrectly connected signal, or a typo. \$\endgroup\$
    – Theraot
    Commented Nov 4, 2023 at 14:46

1 Answer 1


I suspect the reason why your scene transition triggers immediately is the signal you're currently intercepting.

I assume the method _on_Area2D_body_entered() is in the player script. The body_entered() signal is emitted when a PhysicsBody2D or a TileMap enters an Area2D, so your player is probably triggering it by simply standing on the floor, if any.

...when the player touches another CollisionShape2D.

Actually, CollisionShape2D only provide a collision shape to CollisionObject2D-derived Nodes. While based on CollisionShapes, collisions occur among Nodes. There are two main categories of collision signals: areas and bodies. They allow you to know just what area/body a given Node collided with, or both the involved area/body and which particular collision shape collided.

If your colliding object only uses one CollisionShape2D and requires no physics, you can keep things simple and detect the area_entered() signal instead. Moreover, you can move the scene transition logic to the "teleporter" Node in a new script, since scene changing has now become its responsibility, and the player will implement the logic for collisions that only affect its movement or interaction.

Here's a handy script for your "teleporter" object, which in fact I called Teleporter and saved as a separate scene:

extends Area2D

export var go_to_scene: PackedScene

func _on_Teleport_area_entered(area: Area2D):
    if area.name == "Player":

In the Teleporter scene (NOT your level scene), if you connect the area_entered() signal to the method above, you'll have it detect the player entering its collision shape wherever you instantiate the teleporter. Also, exporting the go_to_scene variable as a PackedScene allows you to quickly select the next scene from the Inspector, by clicking on its input field, then Quick Load:

enter image description here

  • \$\begingroup\$ The method _on_Area2D_body_entered() is actually in the Area2D script. will it affect your given guide? \$\endgroup\$ Commented Nov 5, 2023 at 4:20
  • \$\begingroup\$ and also as theraot mentioned. it was wrong for me to use the method "body_entered", \$\endgroup\$ Commented Nov 5, 2023 at 4:25
  • \$\begingroup\$ but thanks for your help! \$\endgroup\$ Commented Nov 5, 2023 at 4:25
  • \$\begingroup\$ "The method (...) is actually in the Area2D script". So is mine. I gave the scene-changing object a different name than its base component type to avoid ambiguity. In my answer, the Player and the Teleport Nodes are both Area2Ds, and none is using body_entered methods. \$\endgroup\$
    – liggiorgio
    Commented Nov 5, 2023 at 15:41
  • \$\begingroup\$ "Will it affect your given guide?". Not at all. Just turn the logic around and check in the Player's script whether the Area2D it is colliding with is named "Teleporter" (or any other name of your choice). However, this will soon clutter the Player script if multiple collision checks are performed there only. That's why I suggest the scene transition logic belongs in the Teleporter script. \$\endgroup\$
    – liggiorgio
    Commented Nov 5, 2023 at 15:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .