godot: Sub - viewports still don't handle _unhandled_input or CollisionObject._input_event()


Bugsquad note: This issue has been confirmed several times already. No need to confirm it further.


I noticed in PR https://github.com/godotengine/godot/pull/15712 the _input event is forwarded to explicitly created Viewports, but _unhandled_input and CollisionObject._input_event() still don’t respond

Godot version: 3.0.stable.official

OS/device including version: OSX 10.13.2 (17C88)

Issue description: The only input events that propagate into sub-viewports are _input.

_unhandled_event and _input_event (for Area2D etc) do not get called.

Steps to reproduce: Open the attached Godot project and run it.

The Red area is in the default Viewport and receives all click events. The green area is a child of the explicit viewport and only receives _inputevents.

Minimal reproduction project: ViewportInputBug.zip

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 18
  • Comments: 31 (18 by maintainers)

Commits related to this issue

Most upvoted comments

Looks like the event object is used by other nodes after the _input call returns, so modifying its position messes up other controls. Here’s a better workaround for the issue:

extends ViewportContainer

func _input( event ):
	if event is InputEventMouse:
		var mouseEvent = event.duplicate()
		mouseEvent.position = get_global_transform().xform_inv(event.global_position)
		$ClassesViewport.unhandled_input(mouseEvent)
	else:
		$ClassesViewport.unhandled_input(event)

Note that this is a temporary workaround until a proper fix is implemented in the engine. It works for me, but may not for you. I wouldn’t leave it in released code. Although I don’t know the full design behind input handling in Godot, it seems weird to call unhandled_input from _input, but it does the job for now.

Here’s a little improvement to @reyalpsirc’s temporary solution to fix the issue @NightGriffin raises, until this is supported by the engine:

extends ViewportContainer

func _input(event):
	if event is InputEventMouse:
		event.position -= rect_global_position
	$Viewport.unhandled_input(event)

This is still an issue. I had to use the workaround in https://github.com/godotengine/godot/issues/17326#issuecomment-431186323

It seems unhandled input was simply not being passed. I will add code so it gets passed, you will have to remove your hacks though.

Okay, it seems that I made it work with this in my case:

extends ViewportContainer

func _input(event):
	$Viewport.unhandled_input(event)

And then set Disable Input and Object Picking to true on the Viewport itself

EDIT

Actually if seems that Disable Input can be false for my case but, I still need Object Picking as true

From what I have seen it only works when the ViewportContainer is at 0,0 (upper left corner)

On Thu, Sep 27, 2018, 4:39 PM Cristiano Santos notifications@github.com wrote:

Okay, it seems that I made it work with this in my case:

extends ViewportContainer

func _input(event): $Viewport.unhandled_input(event)

And then set Disable Input and Object Picking to true on the Viewport itself

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/17326#issuecomment-425275693, or mute the thread https://github.com/notifications/unsubscribe-auth/AFFXbh6gjmgYVslgbZ_wgiOxwRSBCeRMks5ufWHFgaJpZM4Sf8tz .

As a workaround I’ve found doing this:

extends ViewportContainer

func _unhandled_input(event):
	$Viewport.unhandled_input(event)

seems to solve the issue (at least for CollisionObject._input_event())

So perhaps the fix can be copy pasted after all?

@WolfgangSenff yes, this is a known issue, reported in #84258 and there is a PR open to fix this issue: #77926

@ashifolfi then please post your fix, as it could help others like you in the future. Thank you.

Can someone help create a C# version of the fix in https://github.com/godotengine/godot/issues/17326#issuecomment-431186323 ? This issue seems to still be present in Godot today and I can’t seem to figure out how to properly convert this into C# for my project.

I need to also be able to check certain variables before passing the input over.

EDIT: I ended up figuring it out

When someone attempts a fix, please also address being able to disable input handling for all nodes inside a viewport. I need/use it in my project, and this bug is actually a way to make it work, as i can decide whether to pass the unhandled event down (atleast it seems to work as expected in my case) from the manual override that currently is the fix. This is what i currently use and ideally don’t want to lose in functionality when this is fixed:

extends ViewportContainer

var world: Viewport

func _ready():
	world = get_child(0)

func set_active(state:bool):
	visible = state
	world.gui_disable_input = not state
	world.set_process_input(state)
	world.set_process_unhandled_input(state)
	world.set_process_unhandled_key_input(state)

func _unhandled_input(event):
	if not visible:
		return
	world.unhandled_input(event)

I"m seeing this issue in 3.1.1 maybe im doing something wrong?

@Xrayez, unfortunately your workaround didn’t work for me, as I’m trying to use Node._unhandled_input() under the Viewport (rather than CollisionObject._input_event() as you mentioned).

I’m just getting into Godot, and after about 3 months of fiddling around, the ViewportContainer and Viewport nodes are the correct solution to the functionality I’m trying to implement, but this flaw (that _unhandled_input() is not propagated correctly) is keeping it from being successful.

CC @Faless

PS. @JPTeasdale, can you try following the issue template for this and future bugs? It is hard to guess your version and OS otherwise 😃 Also, it would be nice to have a simple project which reproduces the bug, in order to help hunting it.