有个需求,就是在扩展编辑器功能时,有一些配置文件需要读取,现在希望能选取这个东西,而不是每次手填地址。
找了半天unity提供的组件,发现没有提供这个功能呀,这可怎么办???
突然想到unity用的是c#呀,那能不能直接使用c#的系统弹窗,想到就查,结果竟然还真的可以,下面我们来看看要怎么搞。
参考的这个博客的内容:
https://www.jianshu.com/p/e3ef2f45bda0
代码如下:
[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;
}
/// <summary>
/// 从dll加载对话框
/// </summary>
public class DllLoadDialog
{
[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);
[DllImport("shell32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern IntPtr SHBrowseForFolder([In, Out] OpenFileDir ofn);
[DllImport("shell32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern bool SHGetPathFromIDList([In] IntPtr pidl, [In, Out] char[] fileName);
}
public class OpenDialog
{
/// <summary>
/// 打开文件对话框
/// </summary>
/// <returns></returns>
public static string OpenFileName()
{
OpenFileName openFileName = new OpenFileName();
openFileName.structSize = Marshal.SizeOf(openFileName);
openFileName.filter = "配置文件(*.txt)\0*.txt\0All Files\0*.*\0\0";
openFileName.file = new string(new char[256]);
openFileName.maxFile = openFileName.file.Length;
openFileName.fileTitle = new string(new char[64]);
openFileName.maxFileTitle = openFileName.fileTitle.Length;
openFileName.initialDir = Application.dataPath; // 默认路径
openFileName.title = "窗口标题";
// 注意 一下项目不一定要全选 但是0x00000008项不要缺少
// OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR
openFileName.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;
if (DllLoadDialog.GetOpenFileName(openFileName))
{
// Debug.LogFormat("OpenFileName file = {0} fileTitle = {1}", openFileName.file, openFileName.fileTitle);
return openFileName.file;
}
return null;
}
/// <summary>
/// 另存为对话框
/// </summary>
/// <returns></returns>
public static string SaveFileName()
{
OpenFileName openFileName = new OpenFileName();
openFileName.structSize = Marshal.SizeOf(openFileName);
openFileName.filter = "配置文件(*.txt)\0*.txt\0All Files\0*.*\0\0";
openFileName.file = new string(new char[256]);
openFileName.maxFile = openFileName.file.Length;
openFileName.fileTitle = new string(new char[64]);
openFileName.maxFileTitle = openFileName.fileTitle.Length;
openFileName.initialDir = Application.dataPath;//默认路径
openFileName.title = "窗口标题";
// 注意 一下项目不一定要全选 但是0x00000008项不要缺少
// OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR
openFileName.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;
if (DllLoadDialog.GetSaveFileName(openFileName))
{
// Debug.LogFormat("SaveFileName file = {0} fileTitle = {1}", openFileName.file, openFileName.fileTitle);
return openFileName.file;
}
return null;
}
public static string OpenFileDir()
{
OpenFileDir openFileDir = new OpenFileDir();
openFileDir.pszDisplayName = new string(new char[2000]); // 存放目录路径缓冲区
openFileDir.lpszTitle = "Open Project"; // 标题
//openFileDir.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX; // 新的样式,带编辑框
IntPtr pidlPtr = DllLoadDialog.SHBrowseForFolder(openFileDir);
char[] charArray = new char[2000];
for (int i = 0; i < 2000; i++)
{
charArray[i] = '\0';
}
DllLoadDialog.SHGetPathFromIDList(pidlPtr, charArray);
string fullDirPath = new String(charArray);
fullDirPath = fullDirPath.Substring(0, fullDirPath.IndexOf('\0'));
// Debug.LogFormat("OpenFileDir = {0}", fullDirPath);
return fullDirPath;
}
}
弹出窗的配置参数是通过我们声明的那个 OPENFILENAME
结构体来控制的,结构体的具体定义可以查看微软的网站
https://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx
最终效果:
PS: initialDir
这个属性没有效果,每次打开的目录都是上次关闭的,第一次打开的目录也不是我设的地方,不知道是什么原因,不过不打算研究了,能用就行了