Unity调用窗口选择外部文件

最近使用Unity时遇到了一个从外界加载文件的需求,这里陈述了两种解决方案。

方案一 利用WindowsForm对话框

  1. Unity本身并不支持 System.Windows.Forms,需要手动导入。在Unity工程文件中建立一个Plugins文件夹,将System.Windows.Forms.dll文件复制到该文件夹中。
  2. System.Windows.Forms.dll免费下载路径:链接,也可以在本机的Unity安装目录下进行查找,以下路径可供参考。

Unity\2019\Editor\Data\MonoBleedingEdge\lib\mono\gac\System.Windows.Forms\4.0.0.0__b77a5c561934e089

  1. 一些文章中要求将API Compatibility Level*修改为.net 2.0,经unity2019版本测试,.net 4.x正常使用。在这里插入图片描述
  2. 引入命名空间:using System.Windows.Forms;
  3. 简单用法如下所示,更多用法参看微软c#官方资料
     private void Start()
    {
        string filePath;
        using (OpenFileDialog openFileDialog = new OpenFileDialog())
       {
           openFileDialog.InitialDirectory = "c:\\";
           if (openFileDialog.ShowDialog() == DialogResult.OK)
          {
              filePath = openFileDialog.FileName;
              Debug.Log(filePath);
          }
       }
    }
  1. 运行结果:
    在这里插入图片描述
    在这里插入图片描述

方案二 引用Comdlg32.dll(非托管的DLL)

方案一实现了对话框调用并获取路径,但是对话框版本较为陈旧,下面的方式更简单美观。
参考资料:
资料一:StructLayout特&性
资料二:C#直接使用DllImport外部Dll的方法
资料三:OpenFileName结构体介绍
资料四:百度资料

  1. 自定义OpenFileName数据接收类
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenFileName
{
    public int structSize = 0;
    public IntPtr dlgOwner = IntPtr.Zero;
    public IntPtr instance = IntPtr.Zero;
    public String filter = null;
    public String customFilter = null;
    public int maxCustFilter = 0;
    public int filterIndex = 0;
    public String file = null;
    public int maxFile = 0;
    public String fileTitle = null;
    public int maxFileTitle = 0;
    public String initialDir = null;
    public String title = null;
    public int flags = 0;
    public short fileOffset = 0;
    public short fileExtension = 0;
    public String defExt = null;
    public IntPtr custData = IntPtr.Zero;
    public IntPtr hook = IntPtr.Zero;
    public String templateName = null;
    public IntPtr reservedPtr = IntPtr.Zero;
    public int reservedInt = 0;
    public int flagsEx = 0;
    public OpenFileName(int FileLenth = 256, int FileTitleLenth=64)
    {
        structSize=Marshal.SizeOf(this);
        file = new string(new char[FileLenth]);
        maxFile = file.Length;
        fileTitle = new string(new char[FileTitleLenth]);
        maxFileTitle = fileTitle.Length;
        title = String.Empty;
        flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000008;
        title = "窗口标题";
        initialDir = Application.streamingAssetsPath.Replace('/', '\\');
    }
}
  1. 导入非托管方法:
public class LocalDialog
{
    [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
    [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern bool GetSaveFileName([In, Out] OpenFileName ofn);
}
  1. 调用过程:
private void Start()
    {
        OpenFileName openFileName = new OpenFileName();
        if (LocalDialog.GetOpenFileName(openFileName))
        {
            Debug.Log(openFileName.file);
            Debug.Log(openFileName.fileTitle);
        } ;
    }
  1. 运行结果:
    在这里插入图片描述
    在这里插入图片描述

  2. OpenFileName参数介绍
    【structSize】:结构的长度(单位bytes)。
    【dlgOwner 】:对话框窗口的拥有者。该成员可以是任何有效的窗口句柄,如果对话框没有拥有者,则可以为NULL。
    【instance】:对话框模板设置,可以为NULL。
    【filter 】:文件过滤器,根据设定来进行初步筛选
    【customFilter 】:静态缓冲区,其中包含一对以空值结尾的过滤器字符串,用于保留用户选择的过滤器模式。
    【maxCustFilter 】:customFilter 缓冲区的大小,该缓冲区的长度至少应为40个字符。如果customFilter 为NULL或指向NULL字符串,则忽略此成员。
    【filterIndex 】:当前所选过滤器的索引,filter 指向的缓冲区包含定义过滤器的字符串对。第一对字符串的索引值为1,第二对字符串的索引值为2,依此类推。索引为零表示lpstrCustomFilter指定的自定义过滤器 。
    【file 】:可用于初始化文件名。如果不需要初始化,则必须为NULL。当GetOpenFileName或GetSaveFileName函数成功返回时,该字符串为选择文件的路径(包含驱动器标识符,路径,文件名以及所选文件的扩展名)。
    【maxFile 】:file 字符串的长度,至少应为256个字符,太小则无法包含文件路径信息。
    【fileTitle 】:所选文件的文件名和扩展名(不包含路径信息)。
    【maxFileTitle】:fileTitle 字符串的长度。
    【initialDir】:打开的初始目录。
    【title 】:放置在对话框标题栏中的字符串。
    【flags 】:用于初始化对话框的标志位,OFN(OpenFileName),具体编码含义查看 参考资料三
    【fileOffset 】:从路径开头到File指向的字符串中的文件名的从零开始的偏移量,以字符为单位。
    【fileExtension 】:从路径的开头到lpstrFile指向的字符串中的文件扩展名的从零开始的偏移量,以字符为单位。
    【defExt 】:默认扩展名。
    【custData 】:系统传递给由lpfnHook成员标识的挂钩过程的应用程序定义的数据。
    【hook 】:指向Hook的指针
    【templateName 】:hInstance成员标识的模块中对话框模板资源的名称。
    【reservedPtr 】:保留指针,未使用
    【reservedInt 】:保留int参数,未使用
    【flagsEx 】:一组位标志可用于初始化对话框。当前,该成员可以为零或以下标志。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值