原文:https://gameinstitute.qq.com/community/detail/125225
ScriptableWizard可以参考:https://liuhaowen.blog.csdn.net/article/details/106737295
Gizmos:https://blog.csdn.net/qq_35030499/article/details/88658452
一、UnityEditor
1.[MenuItem(名字)]
声明在一个函数上方,告知编译器给Unity3D编辑器添加一个菜单项,并且当点击该菜单项的时候调用该函数。
例如:%t是ctrl+T
//在Asset窗口右键添加方法,可以具体到路径
[MenuItem("Assets/在Project目录里右键1")] private static void Assets_right_btn1() { Debug.Log("在Project目录里右键1"); }
//Hierarchy添加方法
[MenuItem(("GameObject/保存当前场景"), false, -1)]
2.Selection类
获取当前选中的文件。
3.[ContextMenu("XXX")]
为继承自MonoBehaviour的类的右键添加方法
4.AddComponentMenu
[AddComponentMenu("组件菜单/ComponentMenu")]
public class ComponentMenuTest : MonoBehaviour {
}
5.GUILayout.Button("打开")
EditorGUILayout.LabelField("。。。。。。。。");
string name = EditorGUILayout.TextField("", GUILayout.Width(150), GUILayout.Height(20));
二、部分文件操作方法:
1.EditorWindow通过拖拽获取文件夹或者文件路径
#region 拖拽相关
Rect rect4 = EditorGUILayout.GetControlRect();
//将上面的框作为文本输入框
selectPath = EditorGUI.TextField(rect4, selectPath);
//subPath = EditorGUILayout.TextField(subPath);
//如果鼠标正在拖拽中或拖拽结束时,并且鼠标所在的位置在文本输入框内
if ((Event.current.type == EventType.DragUpdated || Event.current.type == EventType.DragExited) && rect4.Contains(Event.current.mousePosition))
{
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0)
{
selectPath = DragAndDrop.paths[0];
}
}
#endregion
2.反序列化
public static Object GetObjectFromBytes(byte[] datas)
{
if (datas == null || datas.Length == 0)
return null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream(datas, 0, datas.Length))
{
Object obj = bf.Deserialize(stream) as Object;
stream.Dispose();
return obj;
}
}
3.保存到文件
bool SaveLocalFile(string path, byte[] data)
{
if (File.Exists(path))
File.Delete(path);
using (FileStream fs = new FileStream(path, FileMode.CreateNew))
{
if (fs == null)
return false;
fs.Write(data, 0, data.Length);
AssetDatabase.Refresh();
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
return true;
}
}
4.取文件
public byte[] GetLocalFile(string path)
{
if (File.Exists(path) == false)
return null;
using (FileStream fs = new FileStream(path, FileMode.Open))
{
if (fs == null || fs.Length == 0)
return null;
byte[] data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
return data;
}
}
5.调用windows系统dialog 选择文件夹
#region 调用windows系统dialog 选择文件夹
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenDialogFile
{
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;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenDialogDir
{
public IntPtr hwndOwner = IntPtr.Zero;
public IntPtr pidlRoot = IntPtr.Zero;
public String pszDisplayName = null;
public String lpszTitle = null;
public UInt32 ulFlags = 0;
public IntPtr lpfn = IntPtr.Zero;
public IntPtr lParam = IntPtr.Zero;
public int iImage = 0;
}
public class DllOpenFileDialog
{
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern bool GetOpenFileName([In, Out] OpenDialogFile ofn);
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern bool GetSaveFileName([In, Out] OpenDialogFile ofn);
[DllImport("shell32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern IntPtr SHBrowseForFolder([In, Out] OpenDialogDir ofn);
[DllImport("shell32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern bool SHGetPathFromIDList([In] IntPtr pidl, [In, Out] char[] fileName);
}
public string OpenWindowsDialog()
{
OpenDialogDir ofn2 = new OpenDialogDir();
ofn2.pszDisplayName = new string(new char[2000]); ; // 存放目录路径缓冲区
ofn2.lpszTitle = "Open Project";// 标题
//ofn2.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX; // 新的样式,带编辑框
IntPtr pidlPtr = DllOpenFileDialog.SHBrowseForFolder(ofn2);
char[] charArray = new char[2000];
for (int i = 0; i < 2000; i++)
charArray[i] = ' ';
DllOpenFileDialog.SHGetPathFromIDList(pidlPtr, charArray);
string fullDirPath = new String(charArray);
fullDirPath = fullDirPath.Substring(0, fullDirPath.IndexOf(' '));
return fullDirPath;//这个就是选择的目录路径。
}
#endregion
voidOnGUI(){ targetGo =(GameObject)EditorGUILayout.ObjectField(targetGo,typeof(GameObject),true); subPath = targetGo ==null? subPath : targetGo.name;EditorGUILayout.LabelField(string.Format("保存路径output path:{0}",Path.Combine(path, subPath)));//获得一个长300的框 Rect rect =EditorGUILayout.GetControlRect(GUILayout.Width(300));//将上面的框作为文本输入框 path =EditorGUI.TextField(rect, path); subPath =EditorGUILayout.TextField(subPath);//如果鼠标正在拖拽中或拖拽结束时,并且鼠标所在位置在文本输入框内 if((Event.current.type==EventType.DragUpdated||Event.current.type==EventType.DragExited)&& rect.Contains(Event.current.mousePosition)){//改变鼠标的外表 DragAndDrop.visualMode=DragAndDropVisualMode.Generic;if(DragAndDrop.paths!=null&&DragAndDrop.paths.Length>0){ path =DragAndDrop.paths[0];}}……}