有個需求,就是在擴展編輯器功能時,有一些配置文件需要讀取,現在希望能選取這個東西,而不是每次手填地址。
找了半天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
這個屬性沒有效果,每次打開的目錄都是上次關閉的,第一次打開的目錄也不是我設的地方,不知道是什麼原因,不過不打算研究了,能用就行了