@export_dir
2026/4/14大约 4 分钟
最后更新日期:2026-04-16
最后同步日期:2026-04-15 | Godot 官方原文 — @export_dir
@export_dir
定义
@export_dir 是 GDScript 中的一个注解(annotation),用来在 Godot 编辑器的检查器面板中暴露一个文件夹路径选择器。使用这个注解后,你可以在编辑器里浏览并选择项目内部的某个文件夹(res:// 路径),文件夹路径会以字符串的形式保存在变量中。
简单说,@export_file 是选文件,@export_dir 就是选文件夹。比如你的游戏需要批量加载某个文件夹下所有关卡文件,就可以用 @export_dir 让策划在编辑器里指定关卡文件夹的位置。
在 C# 中,对应的写法是 [Export(PropertyHint.Dir)]。
语法
C#
// 导出文件夹路径选择器
[Export(PropertyHint.Dir)]
public string ExLevelsFolder = "res://levels";GDScript
# 导出文件夹路径选择器
@export_dir var ex_levels_folder: String = "res://levels"参数说明
@export_dir 不需要任何参数——它直接写在变量声明前面即可。
| 说明项 | 详情 |
|---|---|
| 变量类型 | 必须是 String |
| 路径格式 | 以 res:// 开头的项目内部路径 |
| 编辑器控件 | 文件夹浏览按钮,点击后弹出文件夹选择对话框 |
返回值
@export_dir 是一个注解,没有返回值。变量的值是文件夹路径字符串,格式为 res://路径/。
代码示例
C#
using Godot;
using System.Linq;
public partial class LevelManager : Node
{
// ===== 基础用法:指定文件夹路径 =====
[Export(PropertyHint.Dir)]
public string ExLevelsFolder = "res://levels";
public override void _Ready()
{
GD.Print($"关卡文件夹: {ExLevelsFolder}");
}
// 运行结果: 关卡文件夹: res://levels
// ===== 实际场景:批量加载文件夹中的场景 =====
[Export(PropertyHint.Dir)]
public string ExResourceFolder = "res://data/items";
public void LoadAllResources()
{
if (string.IsNullOrEmpty(ExResourceFolder))
{
GD.PrintErr("未设置资源文件夹路径");
return;
}
using var dir = DirAccess.Open(ExResourceFolder);
if (dir == null)
{
GD.PrintErr($"无法打开文件夹: {ExResourceFolder}");
return;
}
int count = 0;
dir.ListDirBegin();
string fileName = dir.GetNext();
while (fileName != "")
{
if (!fileName.StartsWith(".") && fileName.EndsWith(".tres"))
{
GD.Print($"找到资源文件: {fileName}");
count++;
}
fileName = dir.GetNext();
}
dir.ListDirEnd();
GD.Print($"共找到 {count} 个资源文件");
}
// 运行结果: 找到资源文件: sword.tres
// 运行结果: 找到资源文件: shield.tres
// 运行结果: 共找到 2 个资源文件
// ===== 进阶用法:多文件夹管理与动态切换 =====
[Export(PropertyHint.Dir)]
public string ExLocalizationFolder = "res://localization";
[Export(PropertyHint.Dir)]
public string ExAudioFolder = "res://assets/audio";
public void ScanProjectStructure()
{
string[] folders = { ExLocalizationFolder, ExAudioFolder };
string[] names = { "本地化", "音频" };
for (int i = 0; i < folders.Length; i++)
{
if (DirAccess.DirExistsAbsolute(folders[i]))
{
GD.Print($"{names[i]}文件夹存在: {folders[i]}");
}
else
{
GD.PrintErr($"{names[i]}文件夹不存在: {folders[i]}");
}
}
}
// 运行结果: 本地化文件夹存在: res://localization
// 运行结果: 音频文件夹存在: res://assets/audio
}GDScript
extends Node
# ===== 基础用法:指定文件夹路径 =====
@export_dir var ex_levels_folder: String = "res://levels"
func _ready():
print("关卡文件夹: %s" % ex_levels_folder)
# 运行结果: 关卡文件夹: res://levels
# ===== 实际场景:批量加载文件夹中的场景 =====
@export_dir var ex_resource_folder: String = "res://data/items"
func load_all_resources():
if ex_resource_folder.is_empty():
push_error("未设置资源文件夹路径")
return
var dir := DirAccess.open(ex_resource_folder)
if dir == null:
push_error("无法打开文件夹: %s" % ex_resource_folder)
return
var count := 0
dir.list_dir_begin()
var file_name := dir.get_next()
while file_name != "":
if not file_name.begins_with(".") and file_name.ends_with(".tres"):
print("找到资源文件: %s" % file_name)
count += 1
file_name = dir.get_next()
dir.list_dir_end()
print("共找到 %d 个资源文件" % count)
# 运行结果: 找到资源文件: sword.tres
# 运行结果: 找到资源文件: shield.tres
# 运行结果: 共找到 2 个资源文件
# ===== 进阶用法:多文件夹管理与动态切换 =====
@export_dir var ex_localization_folder: String = "res://localization"
@export_dir var ex_audio_folder: String = "res://assets/audio"
func scan_project_structure():
var folders := [ex_localization_folder, ex_audio_folder]
var names := ["本地化", "音频"]
for i in range(folders.size()):
if DirAccess.dir_exists_absolute(folders[i]):
print("%s文件夹存在: %s" % [names[i], folders[i]])
else:
push_error("%s文件夹不存在: %s" % [names[i], folders[i]])
# 运行结果: 本地化文件夹存在: res://localization
# 运行结果: 音频文件夹存在: res://assets/audio注意事项
@export_dir选择的是项目内部路径(res://开头),不是电脑上的绝对路径。如果需要选择项目外部的文件夹,请使用@export_global_dir。- 变量类型必须是
String,路径以res://开头。 - 选择的路径可能不存在——它只是一个字符串,不会自动创建文件夹。使用前应检查文件夹是否存在。
@export_dir不需要任何参数,直接写@export_dir即可。- C# 中使用
[Export(PropertyHint.Dir)]的形式,同样不需要额外的提示字符串。
