SubViewport blocks inputs (but not completely)

Godot Version

v4.2.2.stable.official

Question

Hello! I have been browsing the forums, GitHub and Reddit and I could not find a thread with a problem similar to mine.

My issue is that, if I run a TileMap scene by itself, both the TileMap and its children (StaticBody2Ds) detect input clicks. However, when I put the TileMap inside a SubViewportContainer->SubViewport, only the TileMap gets the input.

I have a series of StaticBody2Ds that I want to do things when the player clicks on them. They are spawned from the TileMap script, as I want them to occupy different tiles and I thought the TileMap was the correct place to code it.

For detecting inputs, I have the following code in:
My StaticBody2D nodes (tried two things to see if any would work):

func _on_input_event(_viewport, event, _shape_idx):
	if event is InputEventMouseButton and event.pressed:
		print_debug('Click detected')

func _gui_input(event):
	 if event is InputEventMouseButton:
		if event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
			print("Clicked on ", self.name)

And the following code in TileMap:

func _input(event):
       if event is InputEventMouseButton and event.pressed:
		print_debug('Click detected on MAP')

Now, if I run the TileMap scene by itself, when I click on a StaticBody2D, it shows both messages. If I click somewhere empty, it shows the message ‘Click detected on MAP’.

Now, the part I haven’t been able to figure for a couple of days now.

My main scene has the following hierarchy:

Node
-VBoxContainer
–Control
—SubViewportContainer
----SubViewport
-----TileMap (the TileMap I mentioned earlier)

The children to TileMap are added during running time.

The odd part is that TileMap still detects when I click it, but the children don’t. I get the message and almost all other interaction I had coded within the TileMap script still works. But the StaticBody2Ds are unaware of the input, and print no message.

A few things I have tested:

  • If I change the hierarchy so as SubViewportContainer has two children, SubViewport and TileMap (making TileMap a direct child of SubViewportContainer), it still won’t work. If I delete SubViewport, then it does work.
  • I changed the mouse filter of the VBoxContainer, the Control node and the SubViewportContainer so their Mouse filter would be set to Ignore. However, this caused the TileMap to stop recieving input and no longer print the messages. If I left them on Ignore, and changed SubViewportContainer Mouse filter back to Pass, then TileMap would detect input again (but StaticBody2D still wouldn’t).

Does anyone know what I am missing? I bet it has to be related to the SubViewport. I found quite a few threads about issues with input in SubViewports, but most of them were trying to do somewhat complex things. I want to know why input propagation stops when arriving to the TileMap and won’t continue.

(Also, not completely related, but the purpose of using a SubViewport is to draw a map separated from a bottom menu. I want the player to be able to scroll around using the mouse on the edges of the map, and to do so, I considered to use the get_viewport().size to calculate how big the map was and establish that way the edges. In case someone would suggest a more simple solution to this)


EDIT: I tried to add to the StaticBody2D script the following handler:

func _input(event):
	if event is InputEventMouseButton:
		if event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
			print("Input on ", self.name)

This works, but now every single StaticBody2D detects that input and I get 5 prints at the same time. The way I had it before adding this, when running the TileMap as a scene, I would only get one message, from the StaticBody2D I had clicked. This solution doesn’t help me, but it can point to some issue on how I am handling the inputs.