Reputation: 35
Within Godot, I am attempting to create a function that would basically dynamically create a property list based on the children nodes (to allow maximum composition). Currently though, I am stuck on one single issue. When I updated the _get_property_list, I don't want to have to hard code a variable to store an int for an enum for every single node. Instead, I want the variables for each node to be created dynamically, i.e., I don't know what variables I will be using within the class until I run the editor.
I tried making a dictionary that will hold all of the variables, but when I overrided the _get and _set funcs as follows:
func _get(key): return propertyHolder[key]
func _set(key, value): propertyHolder[key] = value
I got never ending errors, which tells me that I've gotten something wrong. I couldn't find any _get_variable_list funcs, like the _get_method_list, and so I am stuck. I also considered each node holding their own variable locally and passing it to the parent, but I ultimately ran into the same issue that since the number of nodes is dynamic, I somehow need to dynamically receive these nodes in the parent class. Any advice would be much appreciated.
Upvotes: 1
Views: 1924
Reputation: 40295
I got never ending errors, which tells me that I've gotten something wrong.
From the code you shared, I see that you are not considering the case where the dictionary does not have a key. You could read it with get
:
func _get(key): return propertyHolder.get(key, null)
Here if the dictionary does not have a key
, it will return null
.
If that is not the issue, I'd need to see the errors you got.
I got never ending errors, which tells me that I've gotten something wrong. I couldn't find any _get_variable_list funcs, like the _get_method_list, and so I am stuck.
The "_get_variable_list" is what you are trying to provide in _get_property_list
: get_property_list
.
Of course, do not call get_property_list
from _get_property_list
of the same object, as calling get_property_list
will result in calling _get_property_list
. Last time I tried this resulted in a crash.
Instead, you can read the variables from get_script_property_list
from the script. For example, if you want to automatically export all variables, you can do this:
func _get_property_list() -> Array[Dictionary]:
var result:Array[Dictionary] = []
var script := get_script() as Script
for property in script.get_script_property_list():
if property["type"] == TYPE_NIL:
continue
property["usage"] = PROPERTY_USAGE_DEFAULT
result.append(property)
return result
Here I'm checking the type to skip groups and categories (they are exported as null properties). But you could use them to limit it to only properties defined in the current script:
func _get_property_list() -> Array[Dictionary]:
var result:Array[Dictionary] = []
var script := get_script() as Script
for property in script.get_script_property_list():
if property["type"] == TYPE_NIL:
if (
property["usage"] == PROPERTY_USAGE_CATEGORY
and property["name"] != script.resource_path.get_file()
):
break
continue
property["usage"] = PROPERTY_USAGE_DEFAULT
result.append(property)
return result
I somehow need to dynamically receive these nodes in the parent class
You can connect to these Node
signals: child_entered_tree
, and child_exiting_tree
(you might also be interested in child_order_changed
).
Upvotes: 2