Dynamically adding to exported enum

Godot Version

4.4

Question

Is there a way to have a @tool script that would use either @export or @export_enum and allow for dynamically editing its contents in the inpector?

I’d like to get the current list of children from a given node and populate a list in a dropdown.
Imagine an empty dropdown and under some condition (pressing a button or changing a property) I would add that list as select-able options.
So if I found 2 children, named one and two, the dropdown would change to:

What would the enum/list reference?

Would it be a reference to the child itself in the scene?

I’m not certain what you are asking for is doable, but it might be possible to use an other solution. How would you use this system in your project?

I would be ok to just list the name of each child, i dont need a reference to the actual object.
At this stage what counts is whether or not i can dynamically populate the list of options instead of predefining it.

The idea is that you can place some scenes in your game board, while you design a level, then be able to setup a bunch of parameters by selecting from the dropdown of one scene, the other scene you want to affect.

All of this is in editor, not while the game is running.

I tried making this work, but I couldn’t. I played around with @export_custom and pulling the list of values from a variable, that potentially could be updated in real time with a @tool script and child_order_changed signal. But it fails on the first part, because even just this doesn’t work.

var list: String = "test1,test2,test3"
@export_custom(PROPERTY_HINT_ENUM, list) var test: String

This produces an error Argument 2 of annotation "@export_custom" isn't a constant expression. It would need to be a const instead of var like this, which works:

const list: String = "test1,test2,test3"
@export_custom(PROPERTY_HINT_ENUM, list) var test: String

But that means you can’t update it in real time (as far as I can see).

You probably could get around this with an EditorScript or EditorPlugin if you really need to, but I haven’t tried. It would be slightly more complicated though I imagine. You just need to ask yourself is this worth the effort.

1 Like

No, annotations are only read once and won’t update.

You’ll need to use Object._get_property_list() or Object._validate_property() to dynamically update an exported property.

Example:

@tool
extends Node

@export_storage var values = ["1", "2"]

@export_tool_button("Add Value") var _add_value = func():
	values.append(str(randi()))
	notify_property_list_changed()

var selected_value:int

func _get_property_list() -> Array:
	var props = []

	props.append({
		"name": "selected_value",
		"type": TYPE_INT,
		"hint": PROPERTY_HINT_ENUM,
		"hint_string": ",".join(values)
	})

	return props
4 Likes

oohh, that’s good to know!
Thanks, I’ll give this a go later today

Thanks, works as expected!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.