EXP11.Path|该死的文件名!
大约 3 分钟
路径
一种是相对路径,一种则是绝对路径

Game/XXX
问题
FDirectoryPath
UPROPERTY(EditAnywhere,BlueprintReadWrite)
FDirectoryPath GeneratePath;
点击后会弹出一个目录选择框





// 响应用户点击“选择文件夹”按钮,打开目录选择对话框,并将选中的目录路径写入属性面板中的对应字段
FReply FDirectoryPathStructCustomization::OnPickDirectory(
TSharedRef<IPropertyHandle> PropertyHandle, // 需要设置值的属性句柄(路径字段)
const bool bRelativeToGameContentDir, // 是否将路径相对于游戏内容目录(Content)
const bool bUseRelativePath // 是否将路径转换为工程相对路径
) const
{
FString Directory; // 用于保存用户最终选择的目录路径
// 获取桌面平台模块(用于打开文件/目录对话框)
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
if (DesktopPlatform)
{
// 获取 Slate 中当前按钮所在的窗口句柄,作为对话框的父窗口
TSharedPtr<SWindow> ParentWindow = FSlateApplication::Get().FindWidgetWindow(BrowseButton.ToSharedRef());
void* ParentWindowHandle = (ParentWindow.IsValid() && ParentWindow->GetNativeWindow().IsValid())
? ParentWindow->GetNativeWindow()->GetOSWindowHandle()
: nullptr;
// 获取上一次打开目录的位置(用户体验优化)
FString StartDirectory = FEditorDirectories::Get().GetLastDirectory(ELastDirectory::GENERIC_IMPORT);
// 如果要求相对路径,且初始目录不合法,则重置为 Game Content 目录
if (bRelativeToGameContentDir && !IsValidPath(StartDirectory, bRelativeToGameContentDir))
{
StartDirectory = AbsoluteGameContentDir;
}
// 无限循环:直到用户选择合法目录或取消对话框
for (;;)
{
// 打开目录选择对话框(阻塞式)
if (DesktopPlatform->OpenDirectoryDialog(
ParentWindowHandle,
LOCTEXT("FolderDialogTitle", "Choose a directory").ToString(),
StartDirectory,
Directory))
{
// 校验路径合法性(支持返回失败原因)
FText FailureReason;
if (IsValidPath(Directory, bRelativeToGameContentDir, &FailureReason))
{
// 记录最近使用目录(用于下一次打开对话框)
FEditorDirectories::Get().SetLastDirectory(ELastDirectory::GENERIC_IMPORT, Directory);
// 如果路径相对于 Content,去掉绝对路径前缀
if (bRelativeToGameContentDir)
{
Directory.RightChopInline(AbsoluteGameContentDir.Len(), EAllowShrinking::No);
}
// 如果要求使用工程相对路径(如相对于 .uproject 文件)
else if (bUseRelativePath)
{
Directory = IFileManager::Get().ConvertToRelativePath(*Directory);
}
// 设置属性面板上的值
PropertyHandle->SetValue(Directory);
}
else
{
// 选择的路径不合法,弹出提示并更新起始目录
StartDirectory = Directory;
FMessageDialog::Open(EAppMsgType::Ok, FailureReason);
continue; // 重新打开选择对话框
}
}
break; // 用户取消选择,跳出循环
}
}
return FReply::Handled(); // 返回 Slate 的处理结果
}
宏标记
UPROPERTY(config, EditAnywhere, Category = "PackageSettings", meta = (RelativeToGameContentDir, LongPackageName))
FDirectoryPath GeneratePath;

函数
Engine\Source\Runtime\Core\Public\Misc\Paths.h
FPaths::ValidatePath()
检查路径有效性
FPaths::MakeValidFileName()
自动转换成合法的文件名。