How to detect collision (BEGINNER)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By cookieKing_

I’m making a game where you have to dodge buildings, but I don’t know how to detect collision.

:bust_in_silhouette: Reply From: godot_dev_

In general there are collisions involving the physics engine and movement (e.g.,landing on the floor and not falling through), where there is a post here about detect collisions relating to movement, and there collisions where you handle what to do yourself when the collisions occur. The collision system involves adding collision shapes to an area. For example, in 2D, Area2Ds are used with CollisionShape2D as children nodes to indicate where the collision detection occurs.

To manage what can collide with what, you have to change the collision layer and collision mask of the involved nodes (see this post for details). The idea is some nodes exist on a specific layer and will collide only with other objects with that layer (for example, in a 2D fighting game, enemy hitboxes will collide with friendly hurtboxes and friendly hitboxes will collide with enemy hitboxes. In other words, 2 different layers (a friendly collision layer and an enemy collision layer) exist in this example).

Now for your task, to dodge buildings. Will the buildings simply destroy the player if you don’t dodge correctly? If so, assuming a 2D game, add a Area2D node to your building scene, and add CollisionShape2Ds children to that Area2D. According to the documentation, the collision_layer and collision_mask members are 1 by default, so make sure your player scene’s Area2D also has these set to 1.
Now for your player scene, it could be a KinematicBody2D. By adding an Area2D and following the same logic with adding CollisionShape2Ds to it, you can now detect if the player hits a building. To now destroy the player if the player hits a building, you can handle this by connecting your destruction logic to the area_entered signal of the Area2D of the player. If this signal is emitted by the player’s Area2D, it means the player collided with the building.

This is a high level summary of accomplishing what you need to do.

Is the player node like:
CharacterBody2D
↳Area2d
…↳CollisionShape2D

Where do I put the area_entered and what do I replace the area parameter with?

cookieKing_ | 2023-04-23 00:47

I beleive that scene tree is correct.

You can place the function that connects to the area_entered signal in the script of your CharacterBody2D.

so for example, in your CharacterBody2D script:

func  _on_ready():
    var area2d = $"Area2d"
    area2d.connect("area_entered",self,"_hit_building")

func _hit_building(area): #area is the Area2D of the building
    print("player hit building")

godot_dev_ | 2023-04-23 03:46

How do I get the Area2D of the building if it’s in another scene?

cookieKing_ | 2023-04-23 15:01

Your scene tree will look something like this:

stage (Node2D)

Building

Area2D

CollisionShape2D

Player

Area2D

CollisionShape2D

If the collision_mask and collision_layer and setup properly, if you players moves into a building, if the collision shape of the player intersects with the collision shape of the building, the _hit_building function will be called

godot_dev_ | 2023-04-23 15:53

When I use

func  _on_ready():
    var area2d = $"Area2d"
    area2d.connect("area_entered",self,"_hit_building")

func _hit_building(area): #area is the Area2D of the building
    print("player hit building")

It says

E 0:00:01:0881 emit_signalp: Error calling from signal ‘area_entered’ to callable: ‘Area2D::_on_area_entered’: Method not found.

But when I use

 func _on_area_entered(area):
    	print("crash")

It says

E 0:00:01:0903 emit_signalp: Error calling from signal ‘area_entered’ to callable: ‘Area2D::_on_area_entered’: Method not found.

, but it still works

cookieKing_ | 2023-04-23 16:06

if your code is successfully printing both “player hit building” or “crash”, then I imagine the source of the error is not the code you posted above, and lies in some other scene where you have an Area2D and it’s being connected to a _on_area_entered function that doesn’t exist. If you connected the Area2D signals via the editor, that might be the source of the error code

godot_dev_ | 2023-04-23 18:15