Area2D is not consuming an InputEvent

Hi!
It’s kind of a long post so I’m gonna structure it a little bit.

The Setup

I’m making a game about handling documents with a drag n drop system that mainly handles two things: Documents and Information. It’s kinda like Papers Please. Information nodes are children of document nodes, and both can be dragged around the viewport.
Here’s how the document scene looks like in game, with CollisionShape2Ds (which I use for input) highlited:


As you can see, the document itself has a CollisionShape2D, and the Information nodes also have their own CollisionShape2Ds.
Also here’s the Godot version just in case: v4.2.2.stable.official [15073afe3]

The Problem

It’s simple: I can pick up Information of one document through another, like this:


At first I thought it’s a simple solution: I just consume all events that happen in the “document CollisionShape2D” (The big one).

func _ready():
	# There's some other code here that doesn't matter
	area.connect("input_event", area_input)

func area_input(_viewport: Viewport, event: InputEvent, _shape_idx):
	# Start grab (The next two lines don't matter)
	if event.is_action_pressed(grab_event_name) and not grabbed:
		start_grab()
	_viewport.set_input_as_handled()

Here’s the scene tree for reference (The Area2D is only generated during runtime, this screenshot is from the “Remote” tab):
image
So, problem done, right? Nope. Everything is still happening as described above. Alright, maybe it’s because the input is processed by the other document first?
After all, the order in which _input() is fired depends on the scene tree.
But nope, that’s also not the case. I can pick up the information from Node A through Node B.
So if the scene tree look like that:
image
I still can pickup Node A’s Information, even though Node B get’s the input event first and consumes it.
I tried setting the InputEvent in the Document node (the root of the scene) as handled. But then, all my other nodes stop receiving events! The heck is going on? I thought the root of the scene receives the input last, but if that’s the case, then why does marking the input in the root node as handled stops the children from receiving the event? I thought the children receive the input first!
To quote the docs:

When sending events to its child and descendant nodes, the viewport will do so, as depicted in the following graphic, in a reverse depth-first order, starting with the node at the bottom of the scene tree, and ending at the root node.

I don’t know what to try anymore, so hopefully someone here has an idea of what’s going on.

Im not sure why the input event goes through, but i can recommend you to use control nodes. Control nodes are meant for stuff like this and also they act accordingly to input_events. It will save you a lot of headaches. Collisionshapes are meant for physics while control nodes are meant for user-input

1 Like

Thank you! You really taught me somehting today, that solved a headache.

1 Like