+1 vote

Currently I have 2 objects that needs to trigger some code when they are completely overlapped. How can I detect this?

asked Jun 27, 2016 in Engine by Reyalpsirc (65 points)
retagged Jun 28, 2016 by Reyalpsirc

2 Answers

+1 vote
Best answer
if (object1.get_pos().distance_to(object2.get_pos()) < 0.5):
   #do code

You could check if the position of both objects are the same, but that wouldn't really trigger the code. You can adjust the 0.5 if you think it needs to be more or less precise to trigger it.

answered Jun 27, 2016 by mateusak (1,071 points)
selected Jun 28, 2016 by Reyalpsirc

Isn't there something like the the body_enter and body_exit signals of Area2D that can help with this instead of being constantly checking for the distance of the objects? Or should I join both things in order that distance is only checked once the Area2D fire the body_enter signal?

Based on your answer and with the help of Area2d, I have been able to solve this. Basically, one of the object types registers to the body_enter and body_exit functions with something like this:

func _on_Area2D_body_enter(body):
    if body.is_in_group ("typeA"):
        body.get_parent().setActiveArea(self)

func _on_Area2D_body_exit(body):
    if body.is_in_group ("typeA"):
        body.get_parent().setActiveArea(null)

Then, the other object simply needs something like this:

var activeArea=null
var body=null

func _ready():
    body=get_node("Body")
    body.add_to_group("typeA")
    set_fixed_process(true)

func setActiveArea(area):
    activeArea=area

func _fixed_process(delta):
    if activeArea!=null:
        if (body.get_global_pos().distance_to(activeArea.get_global_pos()) < 10):
            print("Do my stuff here!")

Just as an advice; I don't really think that using Area2D is a good idea at all. I mean, you're not only doing my code, but also the code of the Area2D. I'm not the best to say that, but logic wise I think that using an Area2D is not going to increase performance, just reduce it. I could be wrong, though.

Hmm, but in my case, I have multiple objects of typeA and typeB and the objects of typeA cannot overlap more than 1 object of typeB at a time. That's why I though it would be best to only check the distance once I know which typeB object has started to become overlaped by my typeA object.

Oh, that makes sense.

+2 votes

If it's 2D, you can use Area2D to detect the intersection (so you can avail of the physics engine) and then create a Rect2 with the position and size, since it has an encloses() function which does what you want.

answered Jun 27, 2016 by vnen (785 points)

One of them is an Area2D with a RectangleShape2Dat the moment but, later on, I would like to change this to become a more complex polygon. The encloses function is only available for Rect2?

Only for Rect2. And Rect2 is axis-aligned, so no rotated rectangles. I don't think that SAT (the standard algorithm for physics) can compute this, so I'm afraid you would have to roll your own test. You can still use Areas to report the contact.

A complicated setup would be to put some other shapes around the area, so if it's contacting the center shape but not the borders, then it must be inside.

Hmm, I do have rotations... I was also thinking on SAT but I though there could be an easier way.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.