【Unity3D日常开发】Unity3D中打开Window文件对话框打开文件(PC版)

推荐阅读

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

这篇文章继续讲如何使用Unity3D打开Window文件对话框选择文件。

之前写了一篇:【Unity3D日常开发】Unity3D中适用WEBGL打开Window文件对话框打开/上传文件是基于WEBGL的。

这篇文章是基于PC端的,也就是打包后是exe的版本。

效果图:

二、正文

2-1、解决方案

WEBGL端打开Window文件对话框原理是通过Unity3D去调用JavaScript脚本来完成操作。

PC端是通过调用Window系统的动态链接库Comdlg32.dll来打开Window操作系统中的通用对话框函数。

2-2、实现

(1)引入外部动态库

PC端是通过调用Window系统的动态链接库Comdlg32.dll,这个库是Windows操作系统中包含通用对话框函数(如文件对话框)的库。代码如下:

csharp 复制代码
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]

其中SetLastError = true表示将上一个错误代码设置为非零值。这对于调试和错误处理非常有用。如果调用失败,可以通过检查 Marshal.GetLastWin32Error() 获取错误代码。

而CharSet = CharSet.Auto表示字符集由运行时环境自动选择。

(2)声明GetOpenFileName函数

然后我们需要调用GetOpenFileName函数。这个函数是 Windows 操作系统提供的一个 API 函数,用于显示标准的文件打开对话框。该对话框允许用户选择一个或多个文件,并返回用户所选文件的路径信息。代码如下:

csharp 复制代码
public static extern bool GetOpenFileName([In, Out] OpenFileName ofd);

从关键字extern可以看出,该函数是一个本机方法,其实现并不在C#中,而是在本机代码中。

In, Out\]是修饰符,用于指定参数是既输入又输出的(类似于引用传参)。 **(3)封装OpenFileName对象** 该函数接收一个OpenFileName 类型的参数,因此需要封装一个该类型的类对象,代码如下: ```csharp ///

/// 文件日志类 /// // [特性(布局种类.有序,字符集=字符集.自动)] [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() { this.structSize = Marshal.SizeOf(this); this.filter = "Texure Files(*图片文件)\0*.png;*.jpg;*.bmp;*.jpeg\0"; this.file = new string(new char[256]); this.maxFile = this.file.Length; this.fileTitle = new string(new char[64]); this.maxFileTitle = this.fileTitle.Length; this.initialDir = "C:\\"; //默认路径 this.title = "打开项目"; this.defExt = "JPG"; this.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008; } } ``` 该结构体需要满足WindowsAPI所期望的格式,所以可以将它当作固定用法,这里就不作解释。 **(4)调用GetOpenFileName函数** 上述准备工作做完后就可以调用函数了,代码如下: ```csharp void BtnOpenFileEvent() { OpenFileName path = new OpenFileName(); if (GetOpenFileName(path)) { } } ``` 首先实例化一个`OpenFileName`对象,并且实例化。 然后通过调用`GetOpenFileName`函数,该函数返回一个`bool`值,通常用于表示用户是否成功选择了文件并点击了文件对话框的 "打开" 按钮。因此当返回值为`true`时,返回获取到的文件地址即可。 \***注意,经过实际测试,想要正常打开文件对话框似乎需要确保以管理员权限运行。** **(5)新建一个Image用来显示图片,一个Button用来调用打开文件夹的操作** ```csharp using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; public class OpenFileHandle : MonoBehaviour { public Button BtnOpenFile; public Image showImg; //打开文件 [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)] public static extern bool GetOpenFileName([In, Out] OpenFileName ofd); void Start() { BtnOpenFile.onClick.AddListener(BtnOpenFileEvent); } void BtnOpenFileEvent() { OpenFileName path = new OpenFileName(); if (GetOpenFileName(path)) { string filepath = path.file; StartCoroutine(ReadTexture(filepath, LoadImg)); } } /// /// 读取图片 /// /// /// /// IEnumerator ReadTexture(string path, UnityAction action) { Debug.Log(path); UnityWebRequest request = UnityWebRequestTexture.GetTexture(path); yield return request.SendWebRequest(); if (request.isNetworkError || request.isHttpError) { Debug.Log(request.error); } else { byte[] imgdata = request.downloadHandler.data; action(DownloadHandlerTexture.GetContent(request)); } } /// /// 加载图片 /// /// void LoadImg(Texture texture) { Sprite ImgSprite = Sprite.Create((Texture2D)texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)); showImg.sprite = ImgSprite; } } ``` 效果图: ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/5e3b831f88c444ed892cb535229fe143.gif) ### 三、后记 如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。 *** ** * ** *** 你的点赞就是对博主的支持,有问题记得留言: 博主主页有联系方式。 博主还有跟多宝藏文章等待你的发掘哦: | 专栏 | 方向 | 简介 | |---------------------------------------------------------------------------------|---------|----------------------------------------------------------| | [Unity3D开发小游戏](https://blog.csdn.net/q764424567/category_9291766.html) | 小游戏开发教程 | 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。 | | [Unity3D从入门到进阶](https://blog.csdn.net/q764424567/category_9999472.html) | 入门 | 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。 | | [Unity3D之UGUI](https://blog.csdn.net/q764424567/category_11314591.html) | UGUI | Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。 | | [Unity3D之读取数据](https://blog.csdn.net/q764424567/category_11280711.html) | 文件读取 | 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。 | | [Unity3D之数据集合](https://blog.csdn.net/q764424567/category_11276019.html) | 数据集合 | 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。 | | [Unity3D之VR/AR(虚拟仿真)开发](https://blog.csdn.net/q764424567/category_8308958.html) | 虚拟仿真 | 总结博主工作常见的虚拟仿真需求进行案例讲解。 | | [Unity3D之插件](https://blog.csdn.net/q764424567/category_7171538.html) | 插件 | 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等 | | [Unity3D之日常开发](https://blog.csdn.net/q764424567/category_7171536.html) | 日常记录 | 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等 | | [Unity3D之日常BUG](https://blog.csdn.net/q764424567/category_11359215.html) | 日常记录 | 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。 |

相关推荐
在路上看风景5 小时前
4.5 顶点和片元
unity
iWZXQxBO7 小时前
运动控制卡 倒R角程序 G代码 halcon联合运动控制卡联合相机 运动控制卡内容
音视频
woshikejiaih13 小时前
**播客听书与有声书区别解析2026指南,适配不同场景的音频
大数据·人工智能·python·音视频
Mr数据杨13 小时前
【ComfyUI】AV-FunASR 音频转文本
音视频
LYOBOYI12314 小时前
vscode界面美化
ide·vscode·编辑器
浔川python社15 小时前
关于浔川代码编辑器 v5.0 网页版上线时间的通知
编辑器
凉辰17 小时前
使用uni.createInnerAudioContext()播放指定音频(踩坑分享功能)
开发语言·javascript·音视频
在路上看风景17 小时前
31. Unity 异步加载的底层细节
unity
AI资源库17 小时前
Remotion 一个用 React 程序化制作视频的框架
人工智能·语言模型·音视频
永远都不秃头的程序员(互关)18 小时前
基于CANN的ops-signal仓库实现AIGC音频生成中的动态窗函数融合优化——从STFT预处理到端到端低延迟合成
aigc·音视频