Detecting Total Overlap of CollisionShape2D

Godot Version

4.2.2.stable

Question

Howdy,

I am wondering if there is a way to detect if a CollisionShape2D is completely within the bounds of another CollisionShape2D.

Presently I am checking overlapping areas and have this quick test scene set up using the following script:

area detection

extends Area2D

func _process(delta):
	position = get_global_mouse_position()
	if has_overlapping_areas():
		var areas = get_overlapping_areas()
		_check_placement_valid(areas)
	else:
		$CollisionShape2D.debug_color = Color(0, 0.6, 0.7, 0.42)

func _check_placement_valid(areas: Array[Area2D]):
	for area: Area2D in areas:
		if area.name == "PlacementZone":
			$CollisionShape2D.debug_color = Color(0, 0.642, 0.217, 0.42)

Is there an easy/built-in way to check if the circular collision shape is entirely within the bounds of the larger collision shape?

For your use-case, yes, there’s a way:

extends Area2D


@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D


func _physics_process(delta: float) -> void:
	global_position = get_global_mouse_position()

	var total_dist = 0.0
	for area in get_overlapping_areas():
		for owner_idx in area.get_shape_owners():
			for shape_idx in area.shape_owner_get_shape_count(owner_idx):
				var other_shape = area.shape_owner_get_shape(owner_idx, shape_idx)
				var contacts = collision_shape_2d.shape.collide_and_get_contacts(collision_shape_2d.global_transform, other_shape, area.global_transform * area.shape_owner_get_transform(owner_idx))
				for i in range(0, contacts.size(), 2):
					var a = contacts[i]
					var b = contacts[i+1]
					var dist = (b - a).length()
					total_dist += dist

	if ceil(total_dist) >= collision_shape_2d.shape.radius * 2:
		collision_shape_2d.debug_color = Color.RED
	else:
		collision_shape_2d.debug_color = Color.BLUE

Result:

You could probably make the code easier by using the signals Area2D.area_shape_entered and Area2D.area_shape_exited and keeping track of those values instead.

2 Likes