How do I create an export variable that allows adding a list of complex elements like OptionButtons do

It’s not simple and it would be better if you @export an Array of custom resources but if you still want to get the same behavior as that property then you’ll need to use a @tool script and implement the Object._get(), Object._set(), and Object._get_property_list()

Example:

@tool
extends Node


var my_values = []


func _get(property: StringName) -> Variant:
	if property == "item_count":
		return my_values.size()
	if property.begins_with("items/item_"):
		var parts = property.split("/")
		var index = parts[1].split("_")[1]
		var prop = parts[2]
		return my_values[index.to_int()][prop]

	return null


func _set(property: StringName, value: Variant) -> bool:
	if property == "item_count":
		# The property is the special array
		# resize the array
		my_values.resize(value)
		# and fill it with empty values
		# _set() will be called for all entries in the array
		# reloading its contents
		for i in value:
			my_values[i] = {"name": "", "price": 0}
		# notify that the property list changed
		# to update the array
		notify_property_list_changed()
		return true
	if property.begins_with("items/item_"):
		var parts = property.split("/")
		var index = parts[1].split("_")[1]
		var prop = parts[2]
		my_values[index.to_int()][prop] = value
		return true

	return false


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

	# Special Group Array
	props.append({
		"name": "item_count",
		# class_name format <Group Name>,<prefix>
		"class_name": "Items,items/item_",
		"type": TYPE_INT,
		"usage": PROPERTY_USAGE_ARRAY | PROPERTY_USAGE_DEFAULT
	})

	for i in my_values.size():
		# Each array entry needs to have the prefix items/item_
		# followed by the index and the name of the property
		props.append({
			"name": "items/item_%s/name" % i,
			"type": TYPE_STRING,
			"hint": PROPERTY_HINT_NONE,
		})
		props.append({
			"name": "items/item_%s/price" % i,
			"type": TYPE_INT,
			"hint": PROPERTY_HINT_NONE,
		})

	return props

If you need a more specialized inspector editor then you’ll need to make a plugin and implement an inspector plugin

1 Like