PropertyUsageFlags.PROPERTY_USAGE_SCRIPT_VARIABLE not set for variables found in user script

Godot Version

4.5.1

Question

I am writing a plugin which needs to be able to access all user-defined exported variables attached to an object/script. I am trying to use the property usage flags to distinguish all exported variables from the user-defined ones, however PROPERTY_USAGE_SCRIPT_VARIABLE is not set for any of the variables I have defined in my test script. I am using the following function to define my list:

func _get_exported_properties():
	var array : Array[String]
	for dict in scene_obj.get_property_list():
		var usage = dict.usage
		if usage & PropertyUsageFlags.PROPERTY_USAGE_EDITOR && usage & PropertyUsageFlags.PROPERTY_USAGE_SCRIPT_VARIABLE:
			array.append(dict.name)
	return array

This is the script I am using for testing:

extends Control

@export var my_variable : int
var my_other_variable : int

func _ready() -> void:
	pass

I am expecting to get an array only containing “my_variable” back, but instead I am getting an empty array.

When I only use the PROPERTY_USAGE_EDITOR flag to sort variables I do get “my_variable”, along with other built-in variables.

What am I doing wrong?

PROPERTY_USAGE_SCRIPT_VARIABLE only differenciates the built-in variables from the user exported variables. Object.get_property_list() will return the exported variables but won’t return the variables declared in the root of the script.

Anyway, your check is not correct. Here’s an example:

extends Node


@export var my_var: int = 0
@export_storage var my_storage_var: int = 0
var my_other_var: int = 0


func _ready() -> void:
	var editor_and_variable = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE
	for prop in get_property_list():
		if prop.usage & editor_and_variable == editor_and_variable:
			print(prop.name)

This solution only works for exported variables in the same script/class as the checking function (ie calling self.get_property_list() ). I want to be able to pass in another object and have the function check for user defined exported variables.

I was looking around more and my original issue/question stems from this bug.

Explain what you want to do and where it fails because, as far as I can tell, the snippet I posted above works fine even with other objects.

I want a function that takes in an object as an argument, and returns the names all the exported, user defined variables of that object.

This works then:

func get_exported_properties(object: Object) -> Array[String]:
	var result: Array[String] = []
	var editor_and_variable = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE
	for prop in object.get_property_list():
		if prop.usage & editor_and_variable == editor_and_variable:
			result.append(prop.name)
	return result