【Unity3D日常开发】Unity3D中打开Window文件对话框打开文件(PC版)
推荐阅读
- CSDN主页
- GitHub开源地址
- Unity3D插件分享
- QQ群:398291828
- 小红书
- 小破站
大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新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操作系统中包含通用对话框函数(如文件对话框)的库。代码如下:
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
其中SetLastError = true表示将上一个错误代码设置为非零值。这对于调试和错误处理非常有用。如果调用失败,可以通过检查 Marshal.GetLastWin32Error() 获取错误代码。
而CharSet = CharSet.Auto表示字符集由运行时环境自动选择。
(2)声明GetOpenFileName函数
然后我们需要调用GetOpenFileName函数。这个函数是 Windows 操作系统提供的一个 API 函数,用于显示标准的文件打开对话框。该对话框允许用户选择一个或多个文件,并返回用户所选文件的路径信息。代码如下:
public static extern bool GetOpenFileName([In, Out] OpenFileName ofd);
从关键字extern可以看出,该函数是一个本机方法,其实现并不在C#中,而是在本机代码中。
[In, Out]是修饰符,用于指定参数是既输入又输出的(类似于引用传参)。
(3)封装OpenFileName对象
该函数接收一个OpenFileName 类型的参数,因此需要封装一个该类型的类对象,代码如下:
/// <summary>
/// 文件日志类
/// </summary>
// [特性(布局种类.有序,字符集=字符集.自动)]
[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函数
上述准备工作做完后就可以调用函数了,代码如下:
void BtnOpenFileEvent()
{OpenFileName path = new OpenFileName();if (GetOpenFileName(path)){}
}
首先实例化一个OpenFileName对象,并且实例化。
然后通过调用GetOpenFileName函数,该函数返回一个bool值,通常用于表示用户是否成功选择了文件并点击了文件对话框的 “打开” 按钮。因此当返回值为true时,返回获取到的文件地址即可。
*注意,经过实际测试,想要正常打开文件对话框似乎需要确保以管理员权限运行。
(5)新建一个Image用来显示图片,一个Button用来调用打开文件夹的操作
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));}}/// <summary>/// 读取图片/// </summary>/// <param name="path"></param>/// <param name="action"></param>/// <returns></returns>IEnumerator ReadTexture(string path, UnityAction<Texture> 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));}}/// <summary>/// 加载图片/// </summary>/// <param name="texture"></param>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;}
}
效果图:

三、后记
如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。
你的点赞就是对博主的支持,有问题记得留言:
博主主页有联系方式。
博主还有跟多宝藏文章等待你的发掘哦:
| 专栏 | 方向 | 简介 |
|---|---|---|
| Unity3D开发小游戏 | 小游戏开发教程 | 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。 |
| Unity3D从入门到进阶 | 入门 | 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。 |
| Unity3D之UGUI | UGUI | Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。 |
| Unity3D之读取数据 | 文件读取 | 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。 |
| Unity3D之数据集合 | 数据集合 | 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。 |
| Unity3D之VR/AR(虚拟仿真)开发 | 虚拟仿真 | 总结博主工作常见的虚拟仿真需求进行案例讲解。 |
| Unity3D之插件 | 插件 | 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等 |
| Unity3D之日常开发 | 日常记录 | 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等 |
| Unity3D之日常BUG | 日常记录 | 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。 |
相关文章:
【Unity3D日常开发】Unity3D中打开Window文件对话框打开文件(PC版)
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享QQ群:398291828小红书小破站 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 这篇文章继续讲如何使用Unity3D打开Window文…...
ros2笔记-6.2 使用urdf创建机器人模型
本节主要跟着小鱼老师的视频操作,不同的仿真平台有不同的建模语言,但是几乎都支持URDF。 本节使用URDF创建一个机器人模型。 6.2.1 帮机器人创建一个身体 URDF使用XML来描述机器人的结构和传感器、执行器等信息。 在chapt6/chap6_ws/src创建功能包:r…...
【centos】校时服务创建-频率修改
在 NTP 配置中,校时频率通常是由 NTP 协议自动管理的,NTP 会根据网络延迟和时间偏差动态调整校时频率。不过,您可以通过配置文件中的一些参数来影响 NTP 的行为。 如果想要更改 NTP 的校时频率,可以考虑以下几个方面:…...
J.U.C(1)
目录 JUC(一)一:AQS二:reentrantlock原理1:加锁:2:解锁3:可重入锁原理4:可打断原理5:公平锁原理6:条件变量 三:读写锁(ree…...
计算机网络之---静态路由与动态路由
静态路由 静态路由是由网络管理员手动配置并固定的路由方式。路由器通过静态配置的路由条目来转发数据包,而不会自动调整。它不依赖于任何路由协议。 特点: 手动配置:网络管理员需要手动在路由器中配置每条静态路由。不自动更新:…...
Kubernetes1.28 编译 kubeadm修改证书有效期到 100年.并更新k8s集群证书
文章目录 前言一、资源准备1. 下载对应源码2.安装编译工具3.安装并设置golang 二、修改证书有效期1.修改证书有效期2.修改 CA 证书有效期 三、编译kubeadm四、使用新kubeadm方式1.当部署新集群时,使用该kubeadm进行初始化2.替换现有集群kubeadm操作 前言 kubeadm 默认证书为一…...
C++----STL(string)
引言:STL简介 什么是STL STL(standard template libaray-标准模板库): 是 C标准库的重要组成部分(注意:STL只是C标准库里的一部分,cin和cout也是属于C标准库的),不仅是一个可复用的组件库&…...
利用 Java 爬虫从 yiwugo 根据 ID 获取商品详情
在当今数字化时代,数据是商业决策的关键。对于从事国际贸易的商家来说,精准获取商品的详细信息至关重要。yiwugo 是一个知名的国际贸易平台,拥有海量的商品数据。通过 Java 爬虫技术,我们可以高效地从 yiwugo 根据商品 ID 获取详细…...
vue2修改表单只提交被修改的数据的字段传给后端接口
效果: 步骤一、 vue2修改表单提交的时候,只将修改的数据的字段传给后端接口,没有修改得数据不传参给接口。 在 data 对象中添加一个新的属性,用于存储初始表单数据的副本,与当前表单数据进行比较,找出哪些…...
Flink类加载机制详解
1. 总览 在运行Flink应用时,它会加载各种类,另外我们用户代码也会引入依赖,由于他们依赖版本以及加载顺序等不同,就可能会导致冲突,所以很要必要了解Flink是如何加载类的。 根据加载的来源的不同,我们可以将类分为三种: Java Classpath:Java类路径下,这是Java通用的…...
ClickHouse大数据准实时更新
一、问题背景 最近有一个项目需求,需要对日活跃的3万辆车的定位数据进行分析,并支持查询和统计分析结果。每辆车每天产生1条分析结果数据,要求能够查询过去一年内的所有分析结果。因此,每月需要处理约90万条记录,一年大…...
计算机网络之---端口与套接字
总括 端口:是计算机上用于标识网络服务的数字标识符,用于区分不同的服务或应用程序。套接字:是操作系统提供的用于进程间网络通信的编程接口,允许程序通过它来进行数据的发送、接收和连接管理。关系:端口号用于标识服…...
UE5中制作地形材质
在创作大场景内容时,地形的设计和优化是至关重要的一步。利用UE中的地形系统,开发者能够高效地创建复杂的地形形态,同时保持游戏的性能和视觉效果。 1.在创建地形之前,先新建一个地形使用的混合材质球,添加节点Landsc…...
【Docker】docker compose 安装 Redis Stack
注:整理不易,请不要吝啬你的赞和收藏。 前文 Redis Stack 什么是? 简单来说,Redis Stack 是增强版的 Redis ,它在传统的 Redis 数据库基础上增加了一些高级功能和模块,以支持更多的使用场景和需求。Redis…...
pytest 常用插件
pytest 提供了许多功能强大的插件来增强测试体验和执行能力。以下是一些常用的 pytest 插件介绍,并结合 pytest.main() 进行使用的示例。 1. pytest-xdist pytest-xdist 插件用于并行化测试的执行,可以将测试分配到多个 CPU 核心并行运行,从…...
浅谈云计算05 | 云存储等级及其接口工作原理
一、云存储设备 在当今数字化飞速发展的时代,数据已然成为个人、企业乃至整个社会的核心资产。从日常生活中的珍贵照片、视频,到企业运营里的关键业务文档、客户资料,数据量呈爆炸式增长。面对海量的数据,如何安全、高效且便捷地存…...
linux:文件的创建/删除/复制/移动/查看/查找/权限/类型/压缩/打包,文本处理sed,awk
关于文件的关键词 创建 touch 删除 rm 复制 cp 权限 chmod 移动 mv 查看内容 cat(全部); head(前10行); tail(末尾10行); more,less,grep 查找 find 压缩 gzip ; bzip 打包 tar 编辑 sed 文本处理 awk 创建文件 格式: touch 文件名 删除文件 复制文…...
CentOS 8 如何安装java与mysql
在CentOS 8上安装Java和MySQL的步骤如下: 1. 安装 Java 1.1 安装 OpenJDK(推荐) CentOS 8 默认的软件仓库提供了 OpenJDK 包,您可以直接使用 dnf 命令安装。 # 更新系统 sudo dnf update -y# 安装 OpenJDK 11(Cent…...
Go语言之路————go基本语法、数据类型、变量、常量、输出
Go语言之路————go基本语法、数据类型、变量、常量 前言一、基本语法知识二、数据类型三、常量四、变量五、作用域六、输入输出 前言 我是一名多年Java开发人员,因为工作需要现在要学习go语言,Go语言之路是一个系列,记录着我从0开始接触G…...
音视频入门基础:MPEG2-PS专题(7)——通过FFprobe显示PS流每个packet的信息
音视频入门基础:MPEG2-PS专题系列文章: 音视频入门基础:MPEG2-PS专题(1)——MPEG2-PS官方文档下载 音视频入门基础:MPEG2-PS专题(2)——使用FFmpeg命令生成ps文件 音视频入门基础…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
