Can i remove this duplicate event handler code?

Godot Version

Godot 4.2

Question

i made a hidden object game (GitHub) and it works but it feels inelegant.

There is a list of objects to find, you click on them, they animate and their name is crossed off the list. My implementation: If you have 10 objects there are 10 texture buttons with 10 on_pressed() event handlers that make 10 different calls (passing the object) to the found/animate method and 10 different calls to cross out the name.

# event doesn't take an object-that-was-pressed argument :(
func _on_pimp_pressed(): 
	discover($HiddenObjects/Pimp)
	$PimpLabel.modulate = crossout_color
func _on_ninja_pressed(): 
	discover($HiddenObjects/Ninja)
	$NinjaLabel.modulate = crossout_color
func _on_yet_another_thing_pressed(): 
	discover($HiddenObjects/YetAnotherThing)
	$YetAnotherThingLabel.modulate = crossout_color

Every new object i add means adding more code and that feels wrong. Despite having 6 weeks experience with Godot, making me basically an expert, i don’t know a better way of doing this.

You can create your own button class and expose a property for the target object. Something like this:

extends Button

@export var target_object: CanvasItem
var crossout_color = Color.BLACK


func _ready():
    pressed.connect(_on_pressed)

func _on_pressed():
    owner.discover(target_object)
    target_object.modulate = crossout_color

Now you can attach this script to your buttons, and then in the inspector set the target object for it. That way you can re-use the same script for multiple buttons, as you can simply set different targets for each of them.

Also a note about this owner.discover(target_object) call: In Godot, the owner is the root node of the scene that a node is in. I assume your previous script was attached to the scene root, so by using owner you can call the method there. Of course you could also just move the discover function into the button code, but that depends a bit on your overall setup and what you prefer.

1 Like

Ooh, i hadn’t thought of subclassing the texture button and autoconnecting itself to the pressed() event. Yeah, for my situation that will work nicely.

(in my case the object rendered on screen that you have to click and then it tweens itself away is the button so target_object would be self which makes this extra efficient)

1 Like