You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity构建后EditorUtility.OpenFilePanel报错,求打包可用替代方案

替代Unity EditorUtility.OpenFilePanel的运行时文件选择方案

方案1:Unity官方运行时文件选择API(Windows专属,Unity 2020.1+)

Unity 2020.1及以上版本提供了UnityEngine.Windows.FilePicker类,专门用于Windows平台的运行时文件选择,无需额外依赖,用法示例:

using UnityEngine;
using UnityEngine.Windows;

public class FilePickerHandler : MonoBehaviour
{
    public void TriggerFilePicker()
    {
        // 配置文件筛选规则,格式为「显示名称|*.后缀」,多规则用分号分隔
        string[] filters = new string[] { "文本文件|*.txt", "所有格式|*.*" };
        FilePicker.ShowOpenFilePanel("选择目标文件", "", filters, false, (string[] selectedPaths) =>
        {
            if (selectedPaths != null && selectedPaths.Length > 0)
            {
                Debug.Log("选中文件路径:" + selectedPaths[0]);
                // 这里添加文件选中后的处理逻辑
            }
        });
    }
}

方案2:跨平台原生API调用

如果需要支持Windows、macOS、Linux多平台,可以通过平台编译宏分别调用各系统的原生文件对话框:

Windows平台(基于System.Windows.Forms)

需要先在Unity编辑器中把项目API兼容级别设置为**.NET Framework**(路径:Edit > Project Settings > Player > Other Settings > Configuration),然后添加对System.Windows.Forms.dll的引用,代码示例:

#if UNITY_STANDALONE_WIN
using System.Windows.Forms;

public void OpenWinFileDialog()
{
    OpenFileDialog fileDialog = new OpenFileDialog();
    fileDialog.Filter = "文本文件|*.txt|所有格式|*.*";
    fileDialog.Title = "选择文件";
    
    if (fileDialog.ShowDialog() == DialogResult.OK)
    {
        string targetPath = fileDialog.FileName;
        Debug.Log("选中文件路径:" + targetPath);
    }
}
#endif

macOS平台(调用Objective-C原生API)

通过DllImport调用macOS的NSOpenPanel:

#if UNITY_STANDALONE_OSX
using System.Runtime.InteropServices;

public static class MacFileSelector
{
    [DllImport("__Internal")]
    private static extern string ShowMacOpenDialog(string fileFilter);

    public static string GetSelectedFile(string filter = "txt")
    {
        return ShowMacOpenDialog(filter);
    }
}

// 使用示例
public void TriggerMacFilePicker()
{
    string selectedPath = MacFileSelector.GetSelectedFile("txt");
    if (!string.IsNullOrEmpty(selectedPath))
    {
        Debug.Log("选中文件路径:" + selectedPath);
    }
}

同时需要在项目Plugins/macOS目录下添加一个Objective-C文件(命名为MacFileDialog.m),内容如下:

#include <Cocoa/Cocoa.h>

const char* ShowMacOpenDialog(const char* filter)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    
    NSOpenPanel* openPanel = [NSOpenPanel openPanel];
    [openPanel setCanChooseFiles:YES];
    [openPanel setCanChooseDirectories:NO];
    [openPanel setAllowedFileTypes:@[ [NSString stringWithUTF8String:filter] ]];
    
    NSString* resultPath = nil;
    if ([openPanel runModal] == NSModalResponseOK)
    {
        resultPath = [[openPanel URL] path];
    }
    
    const char* pathCStr = [resultPath UTF8String];
    char* copiedPath = pathCStr ? strdup(pathCStr) : NULL;
    
    [pool release];
    return copiedPath;
}

Linux平台(调用GTK API)

通过DllImport调用GTK的文件选择对话框:

#if UNITY_STANDALONE_LINUX
using System.Runtime.InteropServices;

public static class LinuxFileSelector
{
    [DllImport("libgtk-3.so.0")]
    private static extern IntPtr gtk_file_chooser_dialog_new(string title, IntPtr parent, int action, string btn1, int resp1, string btn2, int resp2, IntPtr end);
    
    [DllImport("libgtk-3.so.0")]
    private static extern void gtk_widget_show_all(IntPtr dialog);
    
    [DllImport("libgtk-3.so.0")]
    private static extern int gtk_dialog_run(IntPtr dialog);
    
    [DllImport("libgtk-3.so.0")]
    private static extern IntPtr gtk_file_chooser_get_filename(IntPtr dialog);
    
    [DllImport("libglib-2.0.so.0")]
    private static extern void g_free(IntPtr ptr);
    
    [DllImport("libgtk-3.so.0")]
    private static extern void gtk_widget_destroy(IntPtr dialog);
    
    private const int GTK_FILE_CHOOSER_ACTION_OPEN = 0;
    private const int GTK_RESPONSE_OK = -5;

    public static string GetSelectedFile()
    {
        IntPtr dialog = gtk_file_chooser_dialog_new("选择文件", IntPtr.Zero, GTK_FILE_CHOOSER_ACTION_OPEN, "取消", -6, "打开", GTK_RESPONSE_OK, IntPtr.Zero);
        gtk_widget_show_all(dialog);
        
        string resultPath = null;
        if (gtk_dialog_run(dialog) == GTK_RESPONSE_OK)
        {
            IntPtr filenamePtr = gtk_file_chooser_get_filename(dialog);
            resultPath = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(filenamePtr);
            g_free(filenamePtr);
        }
        
        gtk_widget_destroy(dialog);
        return resultPath;
    }
}

// 使用示例
public void TriggerLinuxFilePicker()
{
    string selectedPath = LinuxFileSelector.GetSelectedFile();
    if (!string.IsNullOrEmpty(selectedPath))
    {
        Debug.Log("选中文件路径:" + selectedPath);
    }
}
#endif

方案3:第三方插件

如果不想自行编写跨平台原生代码,可以使用成熟的第三方文件选择插件,这类插件通常已封装好各平台的原生实现,直接调用统一API即可完成文件选择功能。

注意事项

  • 使用System.Windows.Forms时,必须确保项目API兼容级别设置为**.NET Framework**,否则会出现编译错误。
  • 各平台的原生代码需放在对应平台的Plugins子目录下,Unity会自动根据打包平台筛选加载对应的代码。

内容的提问来源于stack exchange,提问作者Miguel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:55:04