diff --git a/core/object/object.h b/core/object/object.h
index 16d8e19eaa0..831bfa43e8d 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -90,6 +90,7 @@ enum PropertyHint {
PROPERTY_HINT_TOOL_BUTTON,
PROPERTY_HINT_ONESHOT, ///< the property will be changed by self after setting, such as AudioStreamPlayer.playing, Particles.emitting.
PROPERTY_HINT_NO_NODEPATH, /// < this property will not contain a NodePath, regardless of type (Array, Dictionary, List, etc.). Needed for SceneTreeDock.
+ PROPERTY_HINT_RES_FROM_DIR, /// hint_text is a directory path. The property lists all relevant resource files in hint_text.
PROPERTY_HINT_MAX,
};
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 38b1ec3554b..b978f724dbb 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -2954,7 +2954,10 @@
Hints that a property will be changed on its own after setting, such as [member AudioStreamPlayer.playing] or [member GPUParticles3D.emitting].
-
+
+ Hints a directory for the [Resource] property to list the resource files from.
+
+
Represents the size of the [enum PropertyHint] enum.
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index caed2a808d4..38c6b314013 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -530,6 +530,13 @@
[/codeblock]
+
+
+
+
+ Export a [Resource] property as a list of resource files in a [param directory].
+
+
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 077ab6f0466..9364e9d70e8 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -119,6 +119,7 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations);
register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations);
register_annotation(MethodInfo("@export_flags_avoidance"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations);
+ register_annotation(MethodInfo("@export_from_dir", PropertyInfo(Variant::STRING, "directory")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations, varray("res://"), true);
register_annotation(MethodInfo("@export_storage"), AnnotationInfo::VARIABLE, &GDScriptParser::export_storage_annotation);
register_annotation(MethodInfo("@export_custom", PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_CLASS_IS_ENUM, "PropertyHint"), PropertyInfo(Variant::STRING, "hint_string"), PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_CLASS_IS_BITFIELD, "PropertyUsageFlags")), AnnotationInfo::VARIABLE, &GDScriptParser::export_custom_annotation, varray(PROPERTY_USAGE_DEFAULT));
register_annotation(MethodInfo("@export_tool_button", PropertyInfo(Variant::STRING, "text"), PropertyInfo(Variant::STRING, "icon")), AnnotationInfo::VARIABLE, &GDScriptParser::export_tool_button_annotation, varray(""));
@@ -4525,6 +4526,13 @@ bool GDScriptParser::export_annotations(AnnotationNode *p_annotation, Node *p_ta
if (export_type.builtin_type == Variant::DICTIONARY) {
variable->export_info.type = Variant::DICTIONARY;
}
+ } else if (p_annotation->name == SNAME("@export_from_dir")) {
+ use_default_variable_type_check = false;
+
+ if (!ClassDB::is_parent_class(export_type.native_type, SNAME("Resource"))) {
+ push_error(R"(Export type can only be a resource.)", p_annotation);
+ return false;
+ }
} else if (p_annotation->name == SNAME("@export")) {
use_default_variable_type_check = false;