Is it possable to export a variable to a node that does not have a script attached

Godot Version

4.5

Question

I have a menu scene with a bunch of buttons each one with a button_pressed signal attached. When the button is pressed the Global.chosen_level variable is set. I would like to set this using an exported property on each button (maybe something called ‘levelData’) but I don’t have a script attached to these buttons. I currently have four ideas for how to do this.

  1. make a new script that just has one line exporting the variable and attach it to all the buttons

  2. The buttons are all laveled ‘level #’ so I could just grap the text property to determine which button was pressed. This feels like a hack though.

  3. just have a seperate pressed signal for each button. This is currently what I’m doing but I don’t like it because the code gets longer the more buttons I add

  4. Export the variables to the buttons from the script that is attached to the root of my menu scene. This last one might not work and is the main reason I posted this question here

blows is the connected functions for two of the buttons

func _on_button_pressed():
    $SFX_Click.play()
    await $SFX_Click.finished
    Global.chosen_level = 1
    get_tree().change_scene_to_file("res://Scenes/stage.tscn")


func _on_button_2_pressed():
    print('button 2')
    $SFX_Click.play()
    await $SFX_Click.finished
    Global.chosen_level = 2
    print(Global.chosen_level)
    get_tree().change_scene_to_file("res://Scenes/stage.tscn")

If anyone has any thoughts about this I would love to hear them. Thanks in advance. :slight_smile:

just make new script - how else would you say to computer that this menu should have this variable

There’s a function that is present in anything that inherits object called set_meta, this might be what you’re looking for.

Ok that is where I was leaning anyway but I was curious if there might be a way to assign a variable to a node from a script on a different node.

OK so after playing around this is what I did:

extends Control



# Called when the node enters the scene tree for the first time.
func _ready():
    $CenterContainer/VBoxContainer/Button.set_meta('level_data', 1)
    $CenterContainer/VBoxContainer/Button2.set_meta('level_data', 2)
    $CenterContainer/VBoxContainer/Button3.set_meta('level_data', 3)
    $CenterContainer/VBoxContainer/Button4.set_meta('level_data', 4)
    $CenterContainer/VBoxContainer/Button5.set_meta('level_data', 5)
    $CenterContainer/VBoxContainer/Button6.set_meta('level_data', 6)
    #pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
    pass



func _on_button_pressed(button_pressed):
    var buttonNode = get_node(button_pressed)
    print('button ' + str(buttonNode.get_meta('level_data')))
    $SFX_Click.play()
    await $SFX_Click.finished
    Global.chosen_level = buttonNode.get_meta('level_data')
    get_tree().change_scene_to_file("res://Scenes/stage.tscn")


func _on_button_mouse_entered():
    $SFX_Hover.play()

Thanks you @tibaverus for suggesting set_meta() method. Now all my buttons are handled with one function. I’m still not sure if this is computationally more efficient but it makes it easier to read. I also learned about adding extra arguments in the signal connection dialog so that was cool. :slight_smile:

Not to be that guy but if my answer helped you, it would be nice if you could mark my answer as the solution.

Sorry I already marked my post as the solusion because it had my final script in it. I don’t know if there is a way to change it to yours :confused:

Edit: Never-mind I figured it out :+1:

I apologise if that came off as petty or mean, I’ve just seen this happen a bit more frequently than usual, but thank you for marking it as a solution! I appreciate it.