Button not triggering pressed signal when clicking on it

Godot Version

4.3

Question

`
Hello all! Hope you’re doing great :smiley:

#What I’m doing
I have a dialogue menu system that works as follow:
1-recup current objectives (from a QuestManager) and NPC (from current interaction) you are talking to.
2-generate one button per objective with an objective index, a label that express what objective it is about and a sprite for cosmetic.
3-you click on the button and with the index it displays the corresponding

#How I am doing it:
The DialogueManager (Node 2D) is connected to a signal that emits when the player character is interacting with something and if the interaction is with a “char” object, it does this:

class_name DialogueManager
extends Node

@export var dialogue_menu : DialogueMenu
#other variables
#stuff happens here

func _on_player_character_interacted(emitter : Node, interactable : Interactable, interaction_type : String, player_position : Vector2, goal_id : String) -> void:
	if interaction_type == "char":
		SignalBusSingleton.newstate_query.emit(self, "gamestatemachine", "selectingdialogue")
		dialogue_data.load_dialogue_data(interactable)
	configure_dialogue(interactable)
	dialogue_menu.global_position = player_position + AppSettingsSingleton.dialogue_menu_offset
	dialogue_menu.visible = true
	for index in range(current_dialogues.size()):
		var dialogue = current_dialogues[index]
		dialogue_menu.add_button(index, dialogue.objective_id, dialogue.dialogue_button_label)
	dialogue_menu.place_buttons()

Then the DialogueMenuManager generates the buttons doing this:

class_name DialogueMenu
extends Control

#region Variables
var is_active : bool = true
var button_nodes : Array[Button] = []
#endregion

#region Methods
func add_button(button_index : int, objective_id : String, label : String) -> void:
	var button_scene = preload("res://Scenes/DialogueButton.tscn")
	var new_button_instance = button_scene.instantiate()
	new_button_instance.index = button_index
	new_button_instance.objective_id = objective_id
	new_button_instance.button_label.text = label
	add_child(new_button_instance)

func place_buttons() -> void:
	if get_child_count() > 0:
		for button in get_children():
			var button_y_position = AppSettingsSingleton.dialogue_button_size.y + AppSettingsSingleton.dialogue_menu_spacing
			button.position.y = button_y_position * button.index

Then the DialogueButtonManager gets ready and connects to itself and emits another signal to say “hey I’ve been clicked!”. Said signal transit through my Signal Bus:

class_name DialogueButtonManager
extends Control

@export var dialogue_button_component : Button
@export var button_sprite : Sprite2D
@export var button_label : RichTextLabel
var index : int
var objective_id : String

func _ready():
	dialogue_button_component.modulate.a = 0.5
	await get_tree().process_frame

	dialogue_button_component.pressed.connect(_on_button_pressed)

#region Methods
func set_up_label():
	button_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
	
func _on_button_pressed():
	SignalBusSingleton.dialogue_button_pressed.emit(self)
#endregion

#Did it ever work?
Yes, it did work. When you clicked on the button, it would emit pressed, then emits dialogue_button_pressed; and the signal would then be used by DialogueManager to unload DialogueMenuManager and load DialogueComponent (the dialogue proper) in its place.
I’d like to add that I have another class of buttons exactly the same for a radial menu, and these buttons work, no issue.
What I changed was, the sprite for my character, that is now way bigger (I changed the pixel art placeholder with my own art in HD)…other than that :confused:

#What doesn’t work anymore?
Now the issue is, the button loads, they are in the tree (so they are instantiated) they appear on screen, but you can’t “press” them. AT ALL.
Even by forcing the “toggle” value to true, they force the “pressed” value to true, through the editor, the code never goes into “func _on_button_pressed()” .

#What I tried to debug
-I already tried to change the type of DialogueButtonManager and DialogueMenuManager to Control to no avail, and it worked without it before.
-I also tried to set the z-index to something like 50, to make sure it is “above” everything else. But maybe I don’t get how z-index works.

Any ideas?

[edit: added a screenshot of the game (the button is on top of the cow character) and of the tree]
`

When this happens to me it is usually because another node is taking the click and not passing it on.

In the debugger panel you have a misc tab that shows you the click and who took it. Although if your clicks are not registering this might not work for you.

Have you checked all your control nodes have ‘mouse’ set to pass? If this is the cause of the issue you can test by temporarily re-arranging your nodes to see if that button starts working (and probably something else will now stop as it is not getting the click anymore).

I sometimes run into this difficulty with multiple canvas layers too, as well as control nodes.

1 Like

First: thank you for taking the time to answer.

Second: you are a godsend!
I didn’t know about the misc tab in the debugger (or didn’t investigate it) and you were absolutely right, something was catching the mouse inputs before it could be read by the button (in this case, it was the RoomComponent I implemented a couple of weeks back)

So the solution was:
-Find all the nodes that inherited the Control class (in my case, the foreground and background of the rooms)
-Put the mouse filter to “IGNORE” so that the click and mouse in/out are not stopped by said controls. I could also use pass in other cases, but here, there is no reason for it to catch anything.

1 Like

Hey thanks, had a frustrating day today and being called a godsend really cheered me up! I was glad to be able to point you in the right direction!

The screen shot you posted looked very interesting as a concept. I look forward to seeing something from you in the showcase, or on twitch or perhaps a work in progress?

Good luck with your game!