• Gui input order with subviewports

I've been in an incredible amount of confusion trying to get nathan hoads dialogue manager to work with my project, and I've just found out what was causing me so much trouble. But I don't have a strong understanding of why and if this should be considered expected behavior.

Here are three configurations of my tests scenes:

The 'Gregor_samsa' node contains a 3d scene with a CharacterBody3d that is controlled with inputs read inside the _unhandled_input function and the 'test_dialogue' node spawns an example dialogue bubble from dialogue manager. When the dialogue gui is onscreen it should be the first to receive the player inputs and set them as handled preventing the player character from being able to move.

This works as expected in example c. (though I had to replace some of the get_viewport().set_input_as_handled() calls with get_tree().root.set_input_as_handled in the example balloon script, I haven't determined why some of those fail when get_viewport() returns a subviewport and why others seem to work as expected.)

In example b both the gui and 3d scene receive player input as unhandled input causing the player to be able to move throughout dialogue sequences.

And example a works as expected again but it bothers me that I have to use a subviewport that otherwise would be unnecessary.

Maybe I am going about something wrong, in my use case I have the 3d scene in a subviewport so that I can apply dithering to the 3d scene that shouldn't be applied to the text, then both the text and the dithering subviewport are placed inside a subviewport that is set to render at 320x240 and then stretch that resolution to a higher resolution and optionally apply crt effects.

I guess I have not experimented with using the backbuffer technique to apply the dithering before it gets scaled up... I might be onto somthing but if someone knowledgeable could explain why subviewports seem to handle input as if you've placed them at the end of the tree that would help me a lot.

award so far I'm just using the example provided by the 'dialogue manager' addon. This is the section that seems to be most responsible for eating the input.

func _on_balloon_gui_input(event: InputEvent) -> void:
	# If the user clicks on the balloon while it's typing then skip typing
	if dialogue_label.is_typing and event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed():
		get_viewport().set_input_as_handled()
		dialogue_label.skip_typing()
		return

	if not is_waiting_for_input: return
	if dialogue_line.responses.size() > 0: return

	# When there are no response options the balloon itself is the clickable thing
	get_viewport().set_input_as_handled()

	if event is InputEventMouseButton and event.is_pressed() and event.button_index == 1:
		next(dialogue_line.next_id)
	elif event.is_action_pressed("ui_accept") and get_viewport().gui_get_focus_owner() == balloon:
		next(dialogue_line.next_id)

which is assigned to the gui_input signal of a Control node containing the dialogue elements.

Though I did find out that I can do my post processing without having to use the nested sub viewport, I hadn't reviewed the post processing section of the online documentation since migrating my test projects to godot 4.

I do intend on trying to run some more tests so that I can understand the limitations of using subviewports (or of the way dialogue manager was coded)

award after a subsequent test, your solution is correct, the problem is with the dialogue manager example and not godot. Though I'm not familiar enough yet with the ins and outs of gdscript to know off hand if nathan is avoiding using accept_input for a reason or if he just doesn't know. But at least now I know this is something that needs to be fixed on the dialogue manager addon end. Thanks

    jonulrich actually I see why the addon developer did not use accept_event(), it appears that in my subsequent test I did not try to use either get_tree().root.set_input_as_handled() or accept_event() in _unhandled_input. The problem is the menu the example uses to display dialogue options, handling input with _input in nodes preceding the menu node seems to prevent changing focus or selecting dialogue options from the menu.