Is there any way to check the collision of an area2D, using the process function?

Godot Version

4.3

Question

Hello, I would like to know if it is possible to check if an area2D collides with another area2D in the process function? I’m creating a Drag&Drop system but I’m having a problem checking if a part of the heart is inside or outside the fitting area:

heartpart.gd

extends Node2D

var number_part:int
var can_drag:bool
var offset:Vector2
var ref_areacollision:Object
var inside_areacollision:bool


func _on_area_touch2d_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
	if event is InputEventMouseButton:
		if event.is_action("tap") && event.is_pressed():
			offset = get_global_mouse_position() - global_position
			can_drag = true
		elif event.is_action("tap") && event.is_released():
			can_drag = false
			if inside_areacollision == true && (number_part == ref_areacollision.index_part):
				print("fit part of the heart")

func _process(delta: float) -> void:
	print(inside_areacollision)
	if can_drag:
		global_position = get_global_mouse_position() - offset


func _on_area_joint2d_area_entered(body: Node2D) -> void:
	if body.is_in_group("droppable"):
		inside_areacollision = true
		ref_areacollision = body.get_parent()
		print(ref_areacollision)

func _on_area_joint2d_area_exited(body: Node2D) -> void:
	if body.is_in_group("droppable"):
		inside_areacollision = false


func _ready() -> void:
	inside_areacollision = false
	
	var word_data = name
	number_part = word_data.right(word_data.length()-9).to_int()
	
	$AreaTouch2D.input_event.connect(_on_area_touch2d_input_event)
	$AreaJoint2D.area_entered.connect(_on_area_joint2d_area_entered)
	$AreaJoint2D.area_exited.connect(_on_area_joint2d_area_exited)

areacollision_parts.gd

var index_part:int


func _ready() -> void:
	$AreaJoint2D.add_to_group("droppable")
	#$Sprite2D.visible = false
	
	var word_data = name
	index_part = word_data.right(word_data.length()-17).to_int()

The bug I’m getting is when the collision area of ​​the “AreaJoint2D” node of the “HeartPart*” comes into contact with the collision area of ​​the “AreaCollision_Part*” node and then comes into contact with another collision area. The variable “inside_areacollision” returns false. Since the “HeartPart*” node left one area and then entered another, it causes this conflict that I don’t know how to resolve.


Does anyone know how I can solve this problem please?

It’s not recommended to operate physics in the _process function. Your code looks pretty simple to just change the rename of _process to _physics_process.

Good morning guys, I found a solution to solve this problem using an array!
For me to continue checking if an Area2D is colliding with one and then with another area, I added them inside an array which in this case would be “array_areacollision:Array”. Then if this Area2D, which in this case is the “HeartPart*” node, leaves one of these areas, the area that left is removed from the array.

So the code looks like this:

heartparts.gd

extends Node2D

var number_part:int
var can_drag:bool
var offset:Vector2
var array_areacollision:Array
var ref_areacollision:Object
var inside_areacollision:bool


func _on_area_touch2d_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
	if event is InputEventMouseButton:
		if event.is_action("tap") && event.is_pressed():
			offset = get_global_mouse_position() - global_position
			can_drag = true
		elif event.is_action("tap") && event.is_released():
			can_drag = false
			if inside_areacollision == true && (number_part == ref_areacollision.index_part):
					print("fit part of the heart")


func _physics_process(delta: float) -> void:
	if not array_areacollision: #Check if my array is empty
		inside_areacollision = false
		ref_areacollision = null
	else:
		if array_areacollision.size() == 1: #If I'm still colliding with some area and I only have one area2d in my array... 
			ref_areacollision = array_areacollision[0].get_parent() #Update the area2D reference variable
	
	if can_drag:
		global_position = get_global_mouse_position() - offset


func _on_area_joint2d_area_entered(body: Node2D) -> void:
	if body.is_in_group("droppable"):
		array_areacollision.append(body) #Add the area inside the array
		inside_areacollision = true
		ref_areacollision = body.get_parent()

func _on_area_joint2d_area_exited(body: Node2D) -> void:
	if body.is_in_group("droppable") && body in array_areacollision:
		array_areacollision.erase(body) #Remove the area inside the array


func _ready() -> void:
	inside_areacollision = false
	
	var word_data = name
	number_part = word_data.right(word_data.length()-9).to_int()
	
	$AreaTouch2D.input_event.connect(_on_area_touch2d_input_event)
	$AreaJoint2D.area_entered.connect(_on_area_joint2d_area_entered)
	$AreaJoint2D.area_exited.connect(_on_area_joint2d_area_exited)

By doing this, I can still check if my area is colliding with something or not using the “inside_areacollision” variable. Thank you for your attention!

1 Like

Thanks, I’ve already made that change here :smile:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.