mousegodot4

Checking for a click on Area2D before it is considered unhandled


I have some Area2D nodes on top of a TileMap. I want to be able to do something when one of those Area2D is clicked, and something else when the click is on the TileMap. How can I achieve this?


In more details:

Doing something when a click is performed on an Area2D is easy: I just need to implement Area2D._input_event. But if I do so, this method is called after TileMap._unhandled_input. Which is a problem because my implementation of TileMap._unhandled_input won't know if it is the Area2D that is supposed to handle this click or not.

So I guess I need to implement another Area2D method, one that would run before TileMap._unhandled_input. I can do it by implementing Area2D._input (or Area2D._unhandled_input) and running set_input_as_handled there. But I'm observing that those methods are called even when the click occurs outside of my Area2D.

So at this point I guess:

Thanks!


Solution

  • After a few days of searching, I came up with this solution:

    1. Add an Area2D as a child node of the TileMap and give it a CollisionShape2D with a shape that covers it.
    2. Implement _input_event on both the existing Area2D and the one that we just added as a child of the TileMap. Call set_input_as_handled() (method of the Viewport) to ensure that if the event is handled by the top Area2D then it's not handled another time [1]
    3. Set physics_object_picking to true on the Viewport to ensure the Area2D on the top handles the event first

    [1]: it seems that with Godot 4.3 an alternative will be to set Viewport._physics_object_picking_first_only to true instead of bothering with marking the event as handled, but at the time of writing this, the latest stable is 4.2