unity工具开发(转)

原文: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是应用在类上的。添加AddComponentMenu后,点击Inspector面板的Add Component按钮或者工具栏上的Component可以选择添加增加的Component菜单,注意类名必须跟文件名相同才能显示!
[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];}}……}

原文地址:https://www.cnblogs.com/mcyushao/p/11804875.html