Check if Area2D fully encloses PhysicsBody2D

:bust_in_silhouette: Reply From: kidscancode

By default, Area2D just checks for overlapping. If overlapping is detected, you could then compare the relative positions of the bodies, but that will require you to know their sizes. This information is in the extents property of the CollisionShape2D’s shape (don’t forget, extents is measured from the center, so it represents half the shape’s size).

You could also build two Rect objects containing the information and use Rect2.encloses().

Below, if body is a reference to the physics body, and area is a reference to the Area2D:

var body_extents = body.get_node('CollisionShape2D').shape.extents
var area_extents = area.get_node('CollisionShape2D').shape.extents
var body_rect = Rect2(body.global_position - body_extents, body_extents * 2)
var area_rect = Rect2(area.global_position - area_extents, area_extents * 2)
if area_rect.encloses(body_rect):
    print("body is fully inside area!")

Note you can cache these values if you need to check them often, and just update the Rect positions whenever you need to perform the check. This is just an explicit example of how to get the information.

Note that this will only work for RectangleShape2D, only if the PhysicsBody2D has only one CollisionShape2D child and only if the PhysicsBody2D has not been rotated or scaled. For a more general solution, I would put extra Area2Ds around the border of the main Area2D, if the body is overlapping with the middle Area2D and not any of the bordering Area2Ds then it’s completely inside the area.

uzimonkey | 2018-12-30 15:52

I have not tried it but probably Shape2D.collide_and_get_contacts can be used to test if overlaps but there are no contacts on the limits.

eons | 2018-12-30 17:19

True, but the original question did request Rect2 shapes. Also, note that a PhysicsBody2D should never be scaled.

kidscancode | 2018-12-30 20:48

@eons this is probably the best solution, certainly much easier to set up than my idea.

uzimonkey | 2018-12-31 04:44

I didn’t manage to make this work, Shape2D.collide_and_get_contacts still reports points of contacts even when there is none, I think it’s a bug.

votagus | 2021-02-11 02:33