I have a button class called PositionActivatedButton that only activates when a Node2D it is given is under it and the space bar is pressed so that i can have a sort of diegetic menu in my game. Since, from what i can gather, UIs are usually built in their own scene and then places in the game scene, currently i have to manually catch the signal from each button in the gui and re-emit it from a script on the gui scene. To counter this and also reduce coupling between the gui script and the PositionActivatedButton class, i thought about exporting a variable of type signal from the PositionActivatedButton class however i can't seem to assign the signal in the editor like i usually would and when i click it nothing happens. Is it not intended for me to be able to export signals or is it just a bug and is the use of exported signals here bad practice / is there any better way to do what i want to do?
just incase here are the scripts:
class_name LevelGui extends Control
@onready var button_holder := $ButtonHolder
@onready var score_label := $ScoreLabel
@onready var messege_label := $MessageLabel
@onready var wins_label := $WinsLabel
@onready var character_swap_button := $ButtonHolder/CharacterSwapButton
var activator: Node2D
signal play_button_pressed
signal quit_button_pressed
signal resume_button_pressed
signal settings_button_pressed
signal character_button_pressed
signal reset_file_button_pressed
signal left_bind_button_pressed
signal right_bind_button_pressed
var messege: String:
set(new_messege):
messege_label.text = new_messege
var score:int :
set = set_score,
get = get_score
var wins: int:
set = set_wins,
get = get_wins
func setup(new_activator: Node2D):
for child in get_children():
recursive_visibility_all(child, false)
activator = new_activator
for child in button_holder.get_children():
if child is PositionActivatedButton:
child.activator = activator
func set_score(new_score: int):
score_label.text = str(new_score)
func get_score() -> int:
return int(score_label.text)
func set_wins(new_wins: int):
wins_label.text = "wins: " + str(new_wins)
func get_wins() -> int:
return int(wins_label.text)
func on_play_button_activated():
play_button_pressed.emit()
func on_quit_button_activated():
quit_button_pressed.emit()
func on_resume_button_activated():
resume_button_pressed.emit()
func on_settings_button_activated():
settings_button_pressed.emit()
func on_character_button_activated():
character_button_pressed.emit()
func on_reset_file_button_activated():
reset_file_button_pressed.emit()
func on_left_bind_button_activated():
left_bind_button_pressed.emit()
func on_right_bind_button_activated():
right_bind_button_pressed.emit()
func activate_character_swap_button():
character_swap_button.set_process(true)
character_swap_button.visible = true
func deactivate_character_swap_button():
character_swap_button.visible = false
character_swap_button.set_process(false)
static func recursive_visibility_all(node: Control, state: bool):
var children := node.get_children()
if len(children) == 0 :
node.visible = state
return
for child in children:
recursive_visibility_all(child, state)
class_name PositionActivatedButton extends BaseButton
var activator: Node2D
signal activated
func _process(_delta: float) -> void:
if not activator:
return
if not visible:
return
if not activator_under():
return
grab_focus()
if not Input.is_action_just_pressed("button_press"):
return
activated.emit()
func activator_under() -> bool:
var lb = position.x
var ub = lb + size.x
if (activator.position.x < lb)\
or (activator.position.x > ub):
return false
return true
as you can see the gui script ends up being very verbose and repetitive which was my initial problem.