Closed DemonBismuth closed 2 months ago
Please upload an MRP to make this easier to test:
.godot
folder in the archive (but keep project.godot
).@AThousandShips Edited my post to include an MRP.
So I'm probably gonna close this issue, but I want to say that this led me down a rabbit hole that showed some creative uses for custom properties that I havent seen anywhere else.
The obvious answer to my issue was that I needed to add var _caudio_clicked
e.g. to the script. However, manually adding them seemed counter to what I had in mind, after the whole point was to create these properties dynamically. What is the point of _get_property_list()
if you still have to add the properties manually? _get_property_list()
already has all the functionality needed, and the properties were still being saved in the packed scene even if they couldn't be assigned.
Another thing that had been bugging me is how to use _set()
and _get()
. I could see the documentation for it, see how it works, but I still didn't really understand the use case. So in the MRP I started doing some tests. Lets say I add var apple
to the script, and have _get_property_list()
add an exported property orange
. Could I use _set()
and _get()
to have orange assign apple? The answer is yes! In fact, doing so seemed to assign both properties to the same value.
"So what?", you may ask, dear Godot user. What I came to discover is that this could be used to assign dictionary and array entries!
var dict : Dictionary
func _get_property_list():
var p = []
p.append({
"name":"entry_1"
"type": TYPE_NODE_PATH,
"hint": PROPERTY_HINT_NODE_PATH_VALID_TYPES,
"usage": PROPERTY_USAGE_DEFAULT,
"hint_string": "AudioStreamPlayer"
})
return p
func _set(property, value):
if property == "entry_1":
if !dict.has(property) || dict[property] != value:
dict[property] = value
elif dict.has(property) && value == null:
dict.erase(property)
func _get(property):
if property == "entry_1":
return dict.get(property)
I tested this, both in editor and in a build. The property saves to the packed scene correctly, saving as both entry_1
and as an item in dict
. That's one way to edit a dictionary! Works easiest if you want String/StringName only keys, but you can get creative. I can easily see looping through the values of an enum to set the property's name in _get_property_list()
and using _set()
to convert it back to an enum key in the dictionary. Also, this is likely useful for editing individual properties within inner resources.
Why does nobody talk about this? Sorry if this post is inappropriate for this thread, but I needed to document this somewhere, since I never knew godot was capable of this. Hope other users will find this useful.
Tested versions
System information
Godot v4.2.2.stable - Windows 10.0.22621 - GLES3 (Compatibility) - NVIDIA GeForce RTX 4070 Ti SUPER (NVIDIA; 31.0.15.5123) - AMD Ryzen 7 7700X 8-Core Processor (16 Threads)
Issue description
I am currently trying to create custom exported NodePath properties so that I may dynamically connect signals to AudioStreamPlayers. From a custom script that extends Panel, I have
_get_property_list()
to create these properties. Here is a snippet:_CONTAINER_AUDIO
is a const dictionary that contains the names of the properties I want exported as keys, and values are their corresponding signals [0], and whether it takes an argument [1]. These NodePath properties do appear in the inspector correctly:However, when trying to assign these properties, nothing happens. I cannot assign AudioStreamPlayer, AudioStreamPlayer2D, or AudioStreamPlayer3D. When trying to access these properties with
get()
, such asget("_caudio_clicked")
orget("clicked")
, I get this error:Invalid type in function 'get_node' in base 'Panel (field_container.gd)'. Cannot convert argument 1 from Nil to NodePath.
I've never tried accessing fully custom variables before, and not ones from a group, so possibly I may have be in error in how I'm attempting to access the property. However, will little documentation on the matter and inability to find this particular issue (custom grouped properties and how to access them) elsewhere online, I'm not sure what else to do.Steps to reproduce
Copy and paste the following code block into a
@tool
script. Then, attempt to assign it from inspector or access it via the methodget()
.Minimal reproduction project (MRP)
Here is an MRP TestMRP.zip