Hello friends! I’m trying to make a skill tree menu with several skill nodes. When you move your mouse over a skill node, I want that’s node’s description to appear in a label box down below by changing the label’s text to match the node’s description text. The nodes and the label are all children of a parent skill tree control node, so how do I check if one of them is being moused over? I know the nodes have a mouse_entered() signal but it would be inefficient to link up each skill to the parent tree and have each of them be their own function. Thank you for the help!
I’d suggest hooking up mouse_entered() for each thing, but doing something like this:
# skill node
func handle_mouse_entered() -> void:
$Label.set_description("Wrestling Pose", "Strike a dramatic pose on a turnbuckle or a nearby tactical rock for a bonus 15% damage on the next attack.")
You can bind extra data when connecting signals, I recommend connecting to the mouse_entered signal and binding the skill nodepath (so you can get the description from the skill) or the entire description directly, the latter is much worse to work in and edit.
How your skill descriptions stored influences this decision, if each skill node has the same script you could connect and bind dynamically on _ready, I believe would be the simplest outcome with about two lines of code.
Is there a way I can combine these all into one function that automatically gets called whenever one is moused over and it passes in which one is moused over? mouse_entered doesn’t pass in anything since it’s unique to each skill node
Yes. Instead of connecting through the editor you can group or child to a common parent and iterate. Using bind to make each function call unique.
func _ready() -> void:
for skill in $Skills.get_children():
var bound_function: Callable = $Label.set_description.bind(skill.desc)
skill.mouse_entered.connect(bound_function)
This code assumes each skill is a child of “Skills”, but you could use groups instead such as for skill in get_tree().get_nodes_in_group("skills") since you may not want to change the scene tree for UI.
This is helpful, especially for checking if the mouse entered each of the children, but how exactly do I bind a function? Sorry if this is a simple question, but I haven’t seen any documentation on this feature yet.
Thank you for the help! This allowed me to directly set the label text to any of the moused over children’s descriptions. I think $label.text = skill.desc would’ve worked too, but this is still helpful for including multiple strings.
You can only use .bind on a Callable/function, and assignment is not a function. You could make your own function to bind if the description is more complicated than only setting text
func set_description(new_description: String) -> void:
$Label.text = new_description
print("Now with a new description! ", new_description)
# AND show text over time
var visible_tween := create_tween()
visible_tween.tween_property($Label, "visible_ratio", 1.0, 0.2).from(0.0)
func _ready() -> void:
for skill in $Skills.get_children():
# Now using set_description
skill.mouse_entered.connect(set_description.bind(skill.desc))