Detect "top" area2d under mouse

Godot Version

4.3.stable

Question

I realize this has been asked several times before, but I still can’t seem to find a good solution.

I have multiple objects in my game that derive from Area2D and may be over/under each other. When the user clicks one, the particular Area2D that receives the MouseInputEvent seems arbitrary, and I want it to be the Area2D that is “on top” (i.e. rendered last).

This is what my input code looks like for my objects:

func _input_event(viewport: Viewport, event: InputEvent, shape_idx: int) -> void:
	# need to check if InputEventMouseButton b/c input order arrival varies
	# and Input.is_action_just_pressed("select") can be true but this
	# event could be another event arriving first
	if event is InputEventMouseButton and Input.is_action_just_pressed("select"):
		get_viewport().set_input_as_handled()
		Globals.select.emit(self)

I have a handler hooked up to that which is able to deselect the previous object and select the clicked object.

Does anyone know what the best approach here is?

I tried making all my objects derive from Control nodes, but that introduced new problems (can’t control the size directly, so click region is incorrect).

You should be able to achieve that for Area2D nodes by using Viewport.physics_object_picking_sort and Viewport.physics_object_picking_first_only.

2 Likes

Thanks, that did it! For anyone else, I added this to my scene _ready():

	get_viewport().physics_object_picking_first_only = false
	get_viewport().physics_object_picking_sort = true
1 Like