Godot Version
v4.5.1.stable.official [f62fdbde1]
Question
How do I get exported properties from a PackedScene? The docs say it should be possible using SceneState as written in get-node-property-count. Unfortunately, neither does the method count my exported property nor does it show with get_node_property_name.
Example
I want to spawn an Item dynamically via code. The Item is a scene containing a Node with the following script attached and a Sprite2D that changes based on the stat (omitted for simplicity):
@tool
extends Area2D
enum StatTypes {HEALTH, DAMAGE, DEFENSE}
signal onPickup
@export var stat: StatTypes = StatTypes.HEALTH
@onready var _sprite: Sprite2D = $Sprite2D
This item should be spawned by ItemSpawner, another scene that contains one node with the following script:
@tool
## Which item to spawn
@export var spawnItem: PackedScene:
set(value):
spawnItem = value
getItemProperties()
var oldSpawnItem: PackedScene
func play() -> void:
var spawnedItem = spawnItem.instantiate()
(spawnedItem as Node2D).position = targetPosition
(spawnedItem as Node2D).rotation = targetRotation
if (targetNode):
targetNode.add_child(spawnedItem)
else:
get_tree().current_scene.add_child(spawnedItem)
onFinished.emit()
func getItemProperties() -> void:
if (spawnItem != oldSpawnItem && spawnItem != null):
var sceneState = spawnItem.get_state()
for idx in range(sceneState.get_node_property_count(0)):
print_rich("[b]Node Property ", idx , " Name[/b] ", sceneState.get_node_property_name(0, idx))
print_rich("[b]Node Property ", idx , " Count[/b] ", sceneState.get_node_property_value(0, idx))
if (sceneState.get_node_property_value(0, idx) is GDScript):
var script = sceneState.get_node_property_value(0, idx) as GDScript
print_rich("[b]Script Property List[/b]", script.get_script_property_list())
oldSpawnItem = spawnItem
Finally, the ItemSpawner is added in another Scene and I set its property spawnItem to the Item mentioned above. Since PackedScenes don’t allow to adjust their exported properties directly, the goal was to read it myself via SceneStates property methods, i.e. get_node_property_name. Unfortunately, it was impossible to get the exported properties. The only way I could actually get exported properties is by reading the script directly and getting the script property list which returns all properties and not just exported ones. The only meaningful way to then get the exported ones is by enforcing a naming convention for exported properties and then filtering properties by those conventions (i.e. use _ as prefix for all non-exported members, etc.).
I feel like this is opaque when the docs say exported properties should be part of the SceneStates property methods. Could someone clarify this or show a simpler way of getting exported properties of a PackedScene?